Вірус для Вконтакте


В черговий день я сидів перед комп'ютером і не знав, чим зайнятися. Прокручуючи свою стрічку вже повернувся до вчорашніх постам, які вже бачив. Перейшовши на свою сторінку подумав про себе: «Боже, всього 160 передплатників. Як же це мало ... ». І відразу ж виникло питання «А як їх збільшити?». Ясна річ, що кожному на розум прийде накрутка. Але для цього потрібно або гроші, або проводити багато часу, підписуючись, роблячи репости або лайка все, що завгодно - це не було виходом.
Пізніше, перед сном, до мене забралася ідея, як це зробити. Ідея полягала в вірусної посиланням, яку отримають майже всі користувачі мережі.

Прокинувшись вранці і попивши кави, я почав реалізовувати цю ідею. Для багатьох вже давно не секрет, що для виконання запитів від імені користувача в VK API, потрібно мати його access_token. Але! на самому сайті цього ключа не потрібно, щоб просто протестувати. Перед початком створення цього Супер вірусу, я хотів просто перевірити його працездатність.
Для тесту і використовував метод friends.add і в поле user_id прописав свій id. Виконавши цю дію, адресний рядок зміниться, на щось подібне до цього:
Адресний рядок


https://vk.com/dev/friends.add?params[user_id]=id


Цю посилання я скоротив через vk.cc і залишив в коментарях до двох популярних груп з привабливим описом. Через півгодини у мене вже було 100 передплатників (було б більше, але мій коментар видалили, а мене забанили). Після цього, я став упевнений, що це спрацює і приступив до його створення.
Вконтакте обмежує доступ до API від одного IP інтервалом в 5 секунд, щоб сервер не перевантажувався. І для вирішення проблеми з частими запитами вони створили метод execute . Цей метод дозволяє викликати кілька методів одночасно зі збереженням алгоритму, чим я і скористався.
Цей вірус в основному спирається на довірливість людей, двома словами - «соціальна інженерія». Кожен з нас напевно перейде по посиланню в повідомленні від свого друга - саме цим я і хотів поневолити світ скористатися.
На створення вірусу у мене пішли приблизно добу, так як зустрів пару перешкод. Про це трохи пізніше. Вірус повинен був працювати так:
  1. Користувач перейшов по посиланню
  2. Метод отримує список всіх друзів і сортує їх по рейтингу
  3. Відправляє повідомлення з текстом «Дивись / * посилання * /»
  4. Повідомлення видаляється у відправника
  5. Додає в друзі і / або підписується в зазначені групи
  6. Друзі, які отримали повідомлення переходять по посиланню
  7. Починаємо з початку

І власне так виглядає цей код в методі:
var a = API.friends.get ({// Метод для отримання списку всіх друзів "order": "hints" // Параметр для сортування по рейтингу}). items; // Отримати тільки список var b = 0; // Змінна для циклу var d = 0; // Змінна для id повідомлення while (a [b]) {d = API.messages.send ({// Метод відправки повідомлення. Повертає id повідомлення "user_id": a [b], // одержувач "message": "Дивись / * посилання * / "// текст повідомлення}); API.messages.delete ({// Видалити повідомлення по його id "message_ids": d}); b = b + 1; // Збільшити b на 1 (++ b або b ++ не працює)} API.friends.add ({ "user_id": "мій id"});
Отримавши посилання, я радісно пішов протестувати на своєму фейковий профілі. Але не тут-то було. Перейшовши за посиланням, мені видало помилку 12: Синтаксична помилка. Чи не очікувалося символу &. Тут і почалися мої перепони.
Як виявилося, сервер для захисту від XML переводить всі знаки. І знак подвійних лапок "просто переводився в & quotes; а консоль
видавала помилку. Одинарні лапки не переводяться, але їх він не прийме, так як синтаксис від JSON.
Так як це моя перша спроба роботи з уразливістю (як і цей пост) на це у мене пішло трохи довше часу. Перші п'ять годин пішли на те, щоб зрозуміти, що ключі можна передавати і без лапок, і цифри писати в лапках теж не обов'язково. Тобто можна так:
API.friends.add ({user_id: 1234567});
Добре, половина проблеми була вирішена. Залишилася лише одна проблема: мені потрібно було придумати, як передати текст повідомлення і слово «hints» для сортування.
Для довідки! Чому передавати параметр hints було обов'язково?


Справа в тому, що навіть на сторінці тесту методу, при підозрілому запиті (наприклад відправка від 3 або 7 повідомленні), потрібно ввести капчу. Не факт, що повідомлення буде надіслано на потрібний людині. Тому передача цього параметра відсортує список так, що перші троє зі списку з більшою ймовірністю в 90% перейдуть за посиланням.


Для вирішення останньої проблеми я подумав використовувати регулярні вирази або щось на зразок, для заміни числа 0 в рядок. Сам я тільки початківець web розробник і не знав, як це робити, і задав запитання на тостері. Отримавши два потрібних мені відповіді з різними шляхами рішень, відразу ж вирішив використовувати їх. І тут знову проблема ...
ВКонтакте API - це не JavaScript і не підтримує його функції на кшталт replace () або toString (). Та й взагалі нічого не підтримує з JS, крім var, return, while, if, else, масивів і операторів порівняння.
Я знову опинився в тупиковій положенні і не знав, що мені робити. Я розповів про це своїм знайомим програмістам з проханням допомогти. Зі словами «Це просто геніально, чувак!» Вони вирішили мені допомогти і пішли копатися в документації до API
Пішло дуже багато часу, поки я думав, як мені вирішити цю проблему. Стало пізно і я пішов спати. Перед сном, мене знову осяяла грандіозна ідея з вирішенням цієї проблеми.
Знову ранок. Попивши свою дозу ранкової кави насамперед я приступив до продовження свого вірусу.
Рішення було досить простим. Адже передаючи числа або змінні з методів, необов'язково писати їх в лапках.
Для мене знадобився мій фейковий профіль. Там я зробив два різних поста з такими текстами:
  • Дивись / * посилання * /
  • hints

Все, що мені було потрібно, це отримати ці записи і записати в змінні, що я і зробив. В результаті у мене вийшов такий код:
var b = 0; // Змінна для циклу var d = 0; // Змінна для id повідомлення var m = API.wall.get ({owner_id: id, // id фейковий сторінки count: 1 // повернути всього 1 пост}). Items [0] .text; // отримати тільки текст статті var h = API.wall.get ({owner_id: id, // id фейковий сторінки count: 1, // повернути всього 1 пост offset: 1 // змістити пости на 1}). Items [0 ] .text; // отримати тільки текст статті var a = API.friends.get ({// Метод для отримання списку всіх друзів order: h // Параметр для сортування по рейтингу}). Items; // Отримати тільки список while (a [b]) {d = API.messages.send ({// Метод відправки повідомлення. Повертає id повідомлення user_id: a [b], // одержувач message: m // текст повідомлення}) ; API.messages.delete ({// Видалити повідомлення по його id message_ids: d}); b = b + 1; // Збільшити b на 1 (++ b або b ++ не працює)} API.friends.add ({ "user_id": "мій id"});
Отримавши посилання, я перевірив його на працездатність і - ура! Все працювало так, як потрібно. З фейковий сторінки був відправлений запит на додавання в друзі і успішно передані повідомлення першим 7 друзям з рейтингу. Стиснувши посилання і поставивши його на перший пост, я з задоволеною посмішкою готувався до Великого Буму!
Щоб ще і знати, скільки людей перейшло за посиланням, я стиснув посилання до php файлу на моєму хостингу, який записував відвідування в БД, і переадресовував до методу з кодом.
Для інтриги я не став оновлювати сторінку кожен раз, а просто вийшов з ВК відразу, після одного коммента. Повернувся приблизно через годину і, подивившись на кількість записів в БД, відчув прилив щастя. Радості не було меж! Більше 5000 переходів. «І цього всього за годину! А що ж буде через два? »- задавався собі питанням. Адже це був мій перший досвід в хакинге.
Вирішивши подивитися скільки все ж набралося особисто на сторінці, я зайшов на сайт і бачу цілих 3 нових передплатника! Не сказати, що я не був здивований. Я нічого не розумів ... У базі було більше 5000 рядків, де майже всі мали індивідуальний IP, а передплатників всього 3. Я почав думати, що я насправді не такий розумний, дещо себе вважав 2 хвилин тому, і що від таких махінації у ВК вже є захист. З такими думками я пішов сумувати.
Минуло вже 2 дні. Перед тим, як йти спати, я вирішив перевірити свій сайт. Заглянувши в базу даних, і заради інтересу подивився таблицю для запису статистики. Там уже набралося більше 25 000 відвідуванні по вірусної посиланням, а передплатників стало менше, тому що відписалися ще й ті, які для мене були тестом ще на початку.
Знову перед сном, я нарешті зрозумів, чому не було нових передплатників, а кількість переходів росло (хто-небудь, напишіть пост, чому саме перед сном приходять рішення? Інакше я сам напишу).
Вся справа була в коді. Метод execute виконує код зберігаючи алгоритм, а метод додавання в друзі був у самому кінці. Він не спрацьовував тому, що подальші методи не виконувалися до тих пір, поки не буде введена капча. Оскільки у всіх моїх «жертв» було більше 8 друзів, природно спрацьовувала капча, а користувачі запідозривши щось, просто закривали вкладку. Запис зберігалася, повідомлення передавалися, а рабів передплатників не стає більше.
Відразу скакнув з ліжка, я вирішив виправити це швидко, щоб до ранку було вже більше десяток тисяч передплатників. Після внесення зміні в php файлі переадресації, я пішов спати з задоволеними думками завтрашньому дні.
Настає ранок і я перевіряю свій профіль, навіть не попивши свою каву. Ура! Передплатників стало менше ...
Я знову був вкрай здивований. Все ж має працювати. Цього разу я вирішив перевірити працездатність посилання на теперішньому профілі. Видаливши код, видалення повідомлення, я перейшов по згенерованої посиланням. Виявляється цю уразливість розробники вже закрили. Код в адресні рядку по переходу вже не спрацьовував
Я не знаю, як вони самі до цього здогадалися. Я тут геній! Чи то і до них дійшло повідомлення, то чи один із знайомих програмістів потай розповів про уразливість, щоб там не було я про це ніколи не дізнаюся.
Я все одно був радий, так як я вперше зміг знайти вразливість у великій мережі. Може іншим це звичайна справа, але для мене це було чимось особливим.І відразу ж виникло питання «А як їх збільшити?
Add?
Чому передавати параметр hints було обов'язково?
А що ж буде через два?
О-небудь, напишіть пост, чому саме перед сном приходять рішення?