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

Денис Бондарев ([email protected], www.livedevice.com)


В наше просвещенное время нежелательной корреспонденцией в социальных сетях уже никого не удивишь: в одноглазниках и контактиках имеет аккаунты большая часть активного населения нашей родины. Это же население представляет собой вкусную пищу для рассыльщиков – тут тебе и ФИО, и возраст, и координаты в пространстве.

Если честно, мы совсем не одобряем сам факт существования спама: нас он раздражает совершенно так же, как и любого другого интернетчика, и нам так же хочется поймать всех спамеров в один большой котел, залить серной кислотой и медленно кипятить на среднем огне. Так, стоп, я увлекся. Почему же мы решились на создание статьи со столь претенциозным названием? А как иначе? Специалистов по информационной безопасности темная сторона силы должна интересовать во всех ее проявлениях. Так что, вперед – окунемся в мир противостояния спама и антиспама, капчи и человеческого фактора, гения и злодейства, Моцарта и Сальери…

Капча и человеческий фактор

«ВКонтакте» очень неплохо защищен от спама. Защита эта, по сути, стандартна для социальных сетей:

  1. Невозможно отправить более нескольких десятков сообщений в сутки пользователям, не являющимися твоими друзьями (и то, если пользователь не запрещал общую отсылку ему таких сообщений).
  2. Время между отправлением сообщений контролируется — система просто не даст отправить сообщение, не выдержав определенный лимит между вызовами скриптов отправки (трех секунд достаточно). Сам понимаешь, реализация многопоточности с авторизацией по одному аккаунту становится неуместна.
  3. Даже если пользователи входят в состав друзей, имеет место определенный лимит в количестве отправленных сообщений. Он довольно большой и, если все-таки превышен, то пользователю предлагается пройти тест captcha.
  4. Два последовательных личных сообщения должны быть различны хотя бы на один символ. Это ограничение всерьез воспринимать не стоит.
  5. При авторизации после пяти неверных попыток предстоит пройти тест captcha. Это не дает организовать самостоятельную автоматическую проверку аккаунтов на валидность.

Самыми желанными для спам-атак в социальных сетях считаются именно лично адресованные или публичные настенные сообщения. Мол, пользователь прочтет их с высокой степенью вероятности, и это действительно так. Комментарии, приглашения в группы/предложения дружбы – все это тоже активно используется народными спамерами, но по эффективности они ниже.

Отсюда следует, что наиболее эффективным подходом будет рассылка сообщений «по друзьям», где серьезных ограничений как таковых нет. Это значит, что спамеры, добыв пароли и логины от аккаунтов пользователей (а их количество исчисляется сотнями и тысячами!), авторизируются под каждым и организовывают рассылку сообщений по друзьям аккаунта-жертвы. Исходя из того, что таких жертв сотни или тысячи, а у каждой — довольно много друзей, количество которых все время возрастает, — это влечет за собой просто огромные массы сообщений и самые негативные последствия от спама! Опять же, возникает вопрос: каким образом спамеры добывают эти самые аккаунты и добывают их массово – сотнями тысяч? Не могу не вспомнить слова великого Альберта Эйнштейна: «Только две вещи бесконечны: вселенная и человеческая глупость, и я не уверен по поводу первой». И это так :). Способы добычи аккаунтов классические – фишинговые сайты, трояны, черви.

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

Мы с тобой – социально-активные личности, у нас много друзей, а у друзей – много личных праздников. Поздравлять их вручную – сущая пытка, поэтому я предлагаю тебе написать скрипт, который будет делать это за нас.

Ниже я покажу, как написать подобный скрипт с использованием Curl и PHP. Назвал я его банально: «API for Spam», а в дальнейшем — просто «afors».

Шаг 1. Подход и функционал класса afors. Авторизация

Поскольку «ВКонтакте» определяет авторизированного пользователя по cookies, нам необходимо их заполучить. Как известно, после введения логина с паролем и отправки их на определенный скрипт, сервер возвращает все cookies, необходимые для беспроблемного использования ресурса. Поскольку нам необходимо продублировать POST-запрос от браузера к скрипту авторизации на сайте, мы его отснифаем. Техника примитивна — берем любой снифер (я рекомендую SmartSniffhttp://www.nirsoft.net) и смотрим через него диалог браузера с сервером «ВКонтакте» при обращении к скрипту авторизации.

Как видно из отснифанных данных, авторизация прошла успешно, и cookies передались без проблем. Теперь давай в точности повторим этот механизм авторизации на сервере «ВКонтакте», используя почти все заголовки в POST-запросе (в частности, присвоим заголовку Accept-Encoding значение identity, чтобы опустить получение данных в сжатом виде). Это тут необязательно, но другие web-ресурсы могут быть очень придирчивы к отсутствию тех или иных заголовков. Как решение – наш запрос должен быть максимально похож на запрос, сформированный браузером. Ниже я буду поочередно описывать основные функции из своего класса автоматической рассылки по «ВКонтакте» (поэтому срочно открой сорцы с нашего DVD и начинай их осиливать под моим трепетным руководством). Возьмем следующую PHP-шную функцию:

login_cook($login,$pass,$captcha_sid,$captcha_key).

Код функции авторизации login_cook() класса «afors»


public $auth_cook; // определяем паблик- переменную
……
…….

$ch=curl_init(); //инициализируем сеанс CURL
// Настраиваем сеанс CURL.
//Подробнее смотрите в исходниках
// задаем целевой скрипт
curl_setopt($ch, CURLOPT_URL,
'http://vkontakte.ru/login.php');
..........................
..........................
// включаем получение заголовков
// определяем тип браузера для маскировки
//установим требование возвращения ответа сервера
//установим реферер
// заносим маскировочные cookies
//определяем заголовки (не все обязательны)
// разрешаем отправку POST-данных
// составляем и отправляем запрос
//заносим пришедший ответ в переменную $answer
// закрываем сессию CURL
..........................
..........................
// проверяем пришедший код на наявность
// текста 'captcha_sid'
if (strpos($answer, 'captcha_sid')<>0)
{
preg_match_all('#sid":"(.*?)"#',$answer,$sid_id);
// возвращаем номер-id теста captcha
return "sid_cap:".$sid_id[1][0];
}
else
{
// проверяем пришедший код на наявность
// текста 'failed'
if (strpos($answer, 'failed')<>0)
return "failed"; // возвращаем 'failed'
else
{
// парсим и заносим в чистом виде cookies
// в переменную $this->auth_cook
preg_match_all('#Set-cookie: (.*;)#UiS',
$answer,$answer);
for($t=0;$t<count($answer[0]);$t++)
$auth_cook.=$answer[0][$t];
preg_match('#remixmid=(.*?);#',$auth_cook,$myid);
$this->auth_cook=str_replace("Set-Cookie:",
"", $auth_cook);
//возвращаем id залогиненного пользователя
return $myid[1];
}
}
...........

Сформированные POST-данные отправляются на скрипт http://vkontakte.ru/login.php. Представленная выше функция login_cook() принимает входящими параметрами логин, пароль, id-номер картинки captcha и разгаданный ключ captcha, соответственно (последние часто необязательны, поэтому могут содержать нулевые значения). Результатом станет возвращение состояния авторизации и занесение cookies в переменную класса $this->auth_cook. В случае успешной авторизации функция возвращает id пользователя и полученные cookies в переменную класса public $auth_cook. Если же авторизация не прошла — то возвращает ответ «failed». А если авторизация безуспешна в течение пяти попыток – возвращает код аутентификации (id) captcha. Например, такой: «sid_cap:213610192404». Зная id, можно отловить само изображение капчи по ссылке http://vkontakte.ru/captcha.php?s=1&sid=213610192404 и ввести дополнительными ее параметрами номер аутентификации captсha с разгаданным ключом на изображении.

Шаг 2. Получение списка друзей

Теперь, когда мы заполучили cookies, авторизовавшись во «ВКонтакте», следующим большим делом будет получение списка специальных номеров — id всех друзей пользователя в системе, по которым далее можно будет отправлять сообщения.

Для этого в классе существует функция fr_rec($cookie), которая входящими данными принимает cookies, полученные, например, функцией login_cook(). Она работает просто: парсит полученный html-код от сервера, обратившись к скрипту по адресу http://pda.vkontakte.ru/write:

Код функции fr_rec() из класса «afors» для получения списка друзей авторизированного пользователя

…………
public $fr_siz; // определяем паблик- переменную
public $fr_mass; // определяем паблик- переменную
………………
………………

$ch=curl_init(); //инициализируем сеанс CURL
// Настраиваем сеанс CURL.
//Подробнее смотрите в исходниках
// задаем целевой скрипт
curl_setopt($ch, CURLOPT_URL, 'http://pda.vkontakte.ru/write');
..........................
..........................
// включаем получение заголовков
// определяем тип браузера для маскировки
//установим требование возвращения ответа сервера
// заносим cookies
//отправляем запрос
//заносим пришедший ответ в переменную $answer
// закрываем сессию CURL
..........................
..........................
// парсим список друзей и заносим их id
// в массив $this->fr_mass, а их количество в
//переменную $this->fr_siz
preg_match_all('#<option value\="([0-9]+)">#UiS',
$answer,$this->fr_mass);
$this->fr_siz=count($this->fr_mass[1]);
}
..........................

Из комментариев видно, что результатом работы является заполнение паблик-переменных public $fr_siz и public $fr_mass, в которых, соответственно, хранится количество друзей в численном виде и массив их id в системе ($fr_mass [1][$x], где x – число от 0 до $fr_siz).

Шаг 3. Преодоление трудностей

Чтобы отправить сообщение пользователю, просто знать его id в системе недостаточно. Продвинутые программеры вконтактика ввели систему специальных хешей, прикрепленных к каждому id участника сети. Особенность этой системы – для разных авторизированных пользователей хеши пользователя по одному id разные, а чтоб отправить сообщение, необходимо передать скрипту как id пользователя, так и его хеши (их по двое для каждого id). Они уникальны для каждого отправителя сообщения. Такой ход был введен для затруднения сбора баз данных пользователей всей системы.

Поскольку рассылать сообщения мы будем по своим друзьям, нам необходимо добыть их хеши по их же id. С этой благородной целью мы используем функцию user_hash($id,$cookie), в которой входящими параметрами являются соответственно: id пользователя, для которого необходимо найти хеш, и твои кукисы. Функция обращается к странице по адресу http://vkontakte.ru/mail.php?act=write&to=.$id, в котором переменная $id содержит номер id интересующего пользователя. Дальше происходит парсинг по html-коду страницы и возвращение массива с искомыми хешами для пользователя. Функция возвращает массив $chas, где в $chas[1] содержится специальный код для параметра chas, а в $chas[2] — код для параметра secure. Данные параметров chas и secure необходимы для разрешения отправки сообщения пользователю, по id которого они были найдены, – и посылаются на скрипт http://vkontakte.ru/mail.php вместе с другими данными.

Приводить здесь код этой функции, как и последующих, думаю, необязательно. Все они похожи по строению на описанные в «Шаге 1» и «Шаге 2». Отличаются лишь содержанием запросов и условий в регулярных выражениях парсинга. В общем, кури диск.

Шаг 4. Функция send_mess() класса «afors»

Опираясь на предыдущие шаги, мы уже можем получить все необходимые параметры для отправки сообщений друзьям. Для этого в классе предназначена функция
send_mess($id,$cash,$sec,$cookie,$titl,$mess,$captcha_sid,$captcha_key). Перечислим входящие параметры: id целевого пользователя; его параметр chas; его параметр secure; свои кукисы; тема сообщения; сам текст сообщения; номер-id для captcha; разгаданный ключ для captcha (последние два могут содержать нулевые значения, если не нужны).
Обращаясь к скрипту по адресу http://vkontakte.ru/mail.php, функция посылает ему сформированный POST-запрос из всех необходимых и ранее добытых нами данных.
И возвращает значение 1 в случае успешной отправки, значение 0 в случае неуспешной отправки или специальный id-номер аутентификации captcha в случае, если система потребовала пройти тест captcha.

Как ты, наверняка, знаешь, после отсылки сообщение добавляется в список отправленных сообщений в аккаунте отправителя. А зачем же нам разводить лишний мусор и палево, если можно после отправки сообщения сразу же его оттуда удалить? Для этого в классе существует функция clean_onemess($cookie) , которая удаляет из списка отправленных последнее сообщение. Ее входящим параметром являются лишь cookies авторизированного пользователя в системе. В случае успешного завершения она возвращает значение 1, иначе — 0.

Шаг 5. Преодолеваем трудности при отправке настенных сообщений

В завершающей части нашего с тобой Марлезонского балета рассмотрим преодоление трудностей в процессе отправки сообщений на стены друзей. Алгоритм очень схож с отправкой личных сообщений: сначала парсим хеши стены для каждого друга, а затем — отправляем сообщение.

Для добычи хешей используется функция user_wall_hash($id,$cookie), которая запрашивает страницу искомого пользователя по адресу http://vkontakte.ru/id.$id, где переменная $id содержит id интересующего пользователя. Тут входящими параметрами являются id пользователя (хеши стены которого надо добыть) и собственные cookies, соответственно. Функция возвращает массив $chas, где $chas[1] содержит специальный код-хеш стены для параметра wall_hash, а $chas[2] — специальный код для параметра mid. Для отсылки сообщения на стену необходимо воспользоваться функцией send_wall($wall_hash,$mid,$cookie,$mess,$captcha_sid,$captcha_key), которая обращается к скрипту по адресу http://vkontakte.ru/wall.php, передавая в него данные методом POST.

Входящими параметрами функции являются соответственно: параметр wall_hash; параметр mid; собственные cookies; само сообщение; специальный id-код теста captcha; и ключ теста captcha (последние два параметра, как и в предыдущих случаях, могут иметь нулевые значения, если не нужны). В случае успешной отправки возвращается значение 1, в случае облома — 0; если система затребовала тест captcha- функция возвращает его id-номер аутентификации.

Наглядные примеры

Свободно использовать описанные выше функции можно и без понимания их сути, но это не путь воина. Поступивший так читатель будет проклят Николаем Gorl’ом, а его проклятие в области современной черной магии дорогого стоит. Для кодеров, желающих познать Дзен кодинга для социальных сетей (вплоть до написания качественных ботов), на диске лежит бонус – класс, написанный на PHP, требующий подключенной библиотеки Curl с версией PHP, начиная с пятой. Ты можешь сам доработать и оптимизировать код или дополнить класс новыми функциями, если сочтешь необходимым, — это дело практики. В любом случае, будут вопросы – пиши мне на почту. В дальнейшем на своем сайте я буду выкладывать обновления этого класса и проводить обсуждения его дополнений и общего качества работы. Присоединяйся!

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

<?
include("afors.php"); // подключаем класс
$m=new afors(); // создаем объект класса
$mess="Hello World"; // пишем текст сообщения
// логинемся и получаем cookies
$m->login_cook("login","password",0,0);
// присваиваем переменной $cookies сами cookies
$cookies=$m->auth_cook;
// вызываем функцию для получения списка друзей
$m->fr_rec($cookies);
// получаем массив хешей личного сообщения для
//11-го друга в списке друзей (fr_mass[1][10])
$g=$m->user_hash($m->fr_mass[1][10],$cookies);
sleep("5"); // делаем задержку в 5 секунд
//посылаем сообщение другу
$re=$m->send_mess($m->fr_mass[1][10],$g[1],
$g[2],$cookies," Hello",$mess, "0","0");
sleep("5"); // делаем задержку в 5 секунд
// очищаем последнее только что отправленное
//сообщение со списка отправленных сообщений
$re2 =$m->clean_onemess($cookies);
// выводим результаты функций send_mess()
//и clean_onemess()
echo $re."::".$re2;
?>

Что такое? Всего 12 строчек весьма легкого, понятного и откомментированного кода? Отлично! Тогда рассмотрим пример отправки сообщения на стену друга:

<?
include("afors.php"); // подключаем класс
$m=new afors(); // создаем объект класса
$mess="Hello World"; // пишем текст сообщения
// логинемся и получаем cookies
$m->login_cook("login"," password ","0","0");
// присваиваем переменной $cookies сами cookies
$cookies=$m->auth_cook;
// вызываем функцию для получения списка друзей
$m->fr_rec($cookies);
// получаем массив хешей настенного сообщения для
//11-го друга в списке друзей (fr_mass[1][10])
$wall=$m->user_wall_hash($m->fr_mass[1][10],
$cookies);
sleep("5"); // делаем задержку в 5 секунд
//посылаем сообщение другу
$re=$m->send_wall($wall[1],$wall[2],$cookies,
$mess,"0","0");
// выводим результаты функции send_wall()
echo $re;
?>

А здесь – и вовсе 10 строчек. Кстати, несмотря на то, что вышеприведенные примеры довольно примитивны, они довольно ясно демонстрируют работу класса.

Заключение

Надеюсь, что приведенная в этой статье информация будет использована исключительно в общественно-полезных целях. «ВКонтакте», как и большинство других популярных социальных сетей, хорошо защитил своих пользователей и дал им возможность в полной мере наслаждаться использованием предоставленных сервисов. Но если человек глуп и наивен, то на просторах интернета никакая программная защита не способна его уберечь. В общем, успехов и удачи в творческих порывах!

WARNING

Ты уже понял, что под «спамом» мы понимаем рассылку поздравлений своим друзьям? Мы не советуем тебе заниматься рассылкой «настоящего» спама и не несем никакой ответственности за противозаконное использование представленной информации!


http://blog.wel.org.ua

работаю админом, прогером сеошнегом :)

Leave a Comment

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Загрузка...
Menu Title