Подделываем результаты конкурсов в ВКонтакте

dice

Во многих социальных сетях, в том числе в ВКонтакте, с некоторых пор стало проводиться множество конкурсов с ценными призами. Речь пойдет о подделке результатов с точки зрения организатора, а конкурсы - те, в которых победитель определяется случайным образом из списка участников.
Итак, существует множество сервисов, которые помогают в проведении сферического конкурса, а доказательством зачастую является записанное видео или прямой эфир, в процессе которого происходит выбор победителя. Давайте рассмотрим, как можно организовать тривиальную подмену результатов, ничем себя не выдав. В качестве примера я рассмотрю вариант с использованием random.org (тот случай, когда организатор генерирует последовательно несколько случайных чисел, чтобы определить страницу и порядковый номер участника на странице), а также вариант с использованием Random.app.

Для начала давайте определимся, как вообще можно провести незаметную подмену в прямом эфире. Самое первое, что приходит в голову: перехватить и модифицировать запросы с помощью промежуточного прокси-сервера (например, Fiddler или Charles), модифицировать результат непосредственно в браузере (например, с помощью Greasemonkey или Tampermonkey), сделать визуальную копию необходимого ресурса на локальном сервере и заворачивать запросы на него с помощью hosts-файла или своего DNS-сервера, и так далее. В конце концов, можно что угодно "нарисовать", если речь идет о видеозаписи проведения конкурса. Остановимся на варианте с модификацией результата в браузере с помощью Tampermonkey или Greasemonkey. На мой взгляд этот вариант наиболее простой для реализации и понимания.
Берем Google Chrome и ставим в него Tampermonkey (есть в Chrome Web Store). В "я без понятия, как это место называется" панели появится новая иконка.

chrome-head

Приступим, для начала random.org. Заходим на сайт и видим в правой части True Random Number Generator, который обычно и используется.

random.org

После беглого изучения мы видим, что этот элемент представляет собой iframe, который загружается по ссылке вида:

Пройдя по ссылке мы можем увидеть, что основная логика реализована в файле iframe.js, после изучения логики становится очевидно, что при нажатии кнопки Generate шлется http-запрос к random.org с желаемым диапазоном, которые возвращает случайное число из диапазона и выводится с помощью вызова функции printNumber из iframe.js. Давайте реализуем простую подмену результата.
Нажмем по вышеупомянутой иконке Tampermonkey и выберем пункт Add a new script. Откроется редактор, куда вы можете сразу скопировать данный скрипт (не забыв после этого нажать кнопку Save):

Как видите - скрипт достаточно простой. В текущем варианте, на 3 по счету нажатии кнопки Generate, мы увидим результат 31337, независимо от заданного диапазона. Чтобы сбросить счетчик нажатий, достаточно перезагрузить страницу в браузере.

Теперь давайте проведем беглый анализ Random.app.

random.app

Мы имеем дело с приложением для ВКонтакте, которое тоже встраивается с помощью iframe. Приложение использует VK API и не взаимодействует с социальной сетью для получения списка возможных победителей. Победитель выбирается случайным образом простым вызовом Math.random. С основной логикой работы Random.app можно ознакомиться, пролистав содержимое следующих скриптов: main.js, random.models.js, random.views.js. Приведу небольшие фрагменты кода, которые отвечают за интересующие нас действия:

main.js

random.view.js

Мы видим, что на элемент с классом .roll-roulette (кнопка Выбрать победителя) вешается обработчик, который выбирает случайного пользователя из заранее сформированного списка и вызывает функцию setWinner, которая отображает победителя. Что ж, давайте сделаем простой скрипт, скопировав часть логики с сайта автора:

Всё опять-таки крайне тривиально, теперь при нажатии кнопки мы всегда будем получать человека с желаемым ID в качестве победителя. Естественно, никто не мешает добавить дополнительной логики в скрипт, чтобы выигрывали не только "избранные", но кому это надо...
Остается еще один простой момент: по-умолчанию в Chrome видна кнопка расширения Tampermonkey и зрители могут что-то заподозрить - не вопрос, нажимаем правой клавишей по ней и выбираем пункт Hide button.

Подведем итоги. Я разобрал часто встречающиеся примеры, однако, ими дело не ограничивается. Еще существуют ресурсы, которые после проведения розыгрыша предоставляют ссылку на результат, чтобы пользователи могли пройти по ней и убедиться что всё честно, но, вы же понимаете, что ресурсом владеют простые люди, а договориться можно с кем угодно. Хотя, пожалуй, можно верить таким ссылкам с random.org (вроде бы доступно только для владельцев платных аккаунтов), но другие ресурсы под большим вопросом, ведь кто мешает, например, мне создать очередной сайт для проведения розыгрышей, раскрутить его и выиграть там, где мне это интересно.

Update (29.01.2017)

Обновленная версия скрипта для Random.app:

Update (04.03.2018)

Скрипт для Randstuff.ru:

Скрипт для Randomizer:

Update (04.06.2018)

Скрипт для Random.app:

Скрипт для Randomizer:

Скрипт для Randstuff.ru:

Update (24.11.2018): Решил выкладывать скрипты на сторонний сервис: https://greasyfork.org/en/users/228137-kaimi (доступны актуальные версии для сервисов Random.app, Random.org и Randstuff.ru).

Подделываем результаты конкурсов в ВКонтакте: 215 комментариев

  1. Здравствуйте. Тоже очень ждем скрипта , думаю что там не сложно поправить , всю суть что сделали опишу.
    Там где прежде было приложение было полностью обновлено, а старую версию с которой мы работали перенесли на новую ссылку https://vk.com/app6108296

    1. Сложно сказать, в принципе, если скрыть плагин, чтобы он не отображался в окне браузера, то не определишь.
      Да и скрипты для tampermonkey - это не единственный способ.

  2. Спасибо за статью! Подскажите, пожалуйста, что нужно дописать в скрипте для рандом орг, чтобы было одновременно 5 чисел на подмену. Заранее спасибо!

    1. Подряд или случайное из 5 чисел бралось?
      Можно убрать проверку счетчика нажатий, сделать desired_number массивом и брать из него подряд или в случайном порядке числа.

      1. Подскажи пожалуйста, как вывести 3 нужных цифр, чтобы не перезагружать каждый раз страницу? То есть в примере в скрипте прописано 31117, я ввел нужную сумму(202) оно выходит первым кликом, остальные наугад. Как сделать так, чтобы все 3 клика были нужными мне, то есть должно выдать такой порядок: 202, 31, 582

        1. Сделать массив из нужных чисел, далее при каждом клике не проверять номер, а просто доставать по очереди числа из массива, пока массив не пустой, если массив закончился, то вызывать оригинальный рандом.

  3. Здравствуйте. Есть актуальная ссылка для скачивания скприпта? На том сайте выдаёт ошибку 404

  4. Каими, огромное спасибо за код, очень выручил. Но назрел вопрос, как переписать его, что б он подряд выбирал нужных победителей.

  5. Здравствуйте, подскажите, пожалуйста как это сделать? Чтобы desired_number был массивом..

      1. Понял, спасибо, а еще такой вопрос: " if (click_ctr == desired_click_number)"
        Мне нужно с этим что-то делать? Т.к я убираю же этот самый счетчик нажатий..

        1. Можно убрать, если предполагается с первого значения выдавать то, что требуется. Можно какую-то логику описать

          1. Квадратные скобки использовать, в них через запятую элементы. Извлекать элемент через метод shift. И видимо убрать или модифицировать проверку на номер клика по счету.

            1. // ==UserScript==
              // @name Random.org
              // @version 0.1
              // @match https://www.random.org/*
              // @description Predictable number generation for True Random Number Generator (https://www.random.org/)
              // @author Kaimi
              // @homepage https://kaimi.io/2016/01/tampering-vk-contest-results/
              // @namespace https://greasyfork.org/users/228137
              // ==/UserScript==

              // Numbers
              var desired_numbers = [31337, 1234, 343];

              if (typeof printNumber != "undefined")
              {
              var origPrintNumber = printNumber;
              printNumber = function()
              {
              if (desired_numbers.length > 0)
              document.getElementById("true-random-integer-generator-result").innerHTML = desired_numbers.shift();
              else
              origPrintNumber();
              }
              };

            2. Привет, всячески испробовать этот метод, но никак не выходит, можешь прописать его здесь еще раз, чтобы при каждой нажатии generate, выходило то число которое нам необходимо, буду очень благодарен.

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

  6. Ну вот выдал мне рондом орг цифры, а как экспортировать репостнувших и пронумеровать ?

    1. Добрый день, разве что убедить их использовать какой-то сервис, который предоставляет ссылку с результатом проведения.
      Т.е. чтобы было не только скриншот/видео, а еще ссылка на результаты.
      Что-то вроде https://randompromo.ru/ , но я не знаток этих сервисов, не пользовался ими.

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

          1. С аватаркой и именем понятно, а как ссылку то подставить на нужного пользователя? Ссылка там действительная остаётся, а не подставленная.

            1. Если речь про Random.app, то там используется метод users.get, если ссылка берется из данных, которые он возвращает, то просто заменять значение параметра в возвращаемом объекте.

  8. Скажите но при работе скрипта число указывается без текса снизу (
    Min: 1, Max: 100
    2021-06-10 15:07:42 UTC - вот этот текст можно также записать в скрипт. ?

  9. здравствуйте! после первого нажатия кнопка "generate" перестает быть активной. Мне кажется это палевно) могу я как-нибудь поменять Ваш скрипт, чтобы это убрать.)) спасибо заранее!

  10. Здравствуйте! После вывода итогов в последней версии, кнопка"generate" перестает быть активной. Как это изменить?

  11. добрый день подскажите как сделать несколько мест победителей?
    по этому вашему коду написал, все работает. но хотелось бы сделать несколько победителей не одного.
    // ==UserScript==
    // @name Randstuff.ru
    // @version 0.2
    // @match *://randstuff.ru/*
    // @run-at document-end
    // @grant none
    // @description Predictable number generation for Randstuff.ru (https://randstuff.ru/number/)
    // @author Kaimi
    // @homepage https://kaimi.io/2016/01/tampering-vk-contest-results/
    // @namespace https://greasyfork.org/users/228137
    // ==/UserScript==

    // Number which will be generated on target click
    var desired_number = 31337;
    var desired_click_number = 3;

    var click_ctr = 0;

    $.ajaxPrefilter
    (
    function(options, originalOptions, jqXHR)
    {
    var originalSuccess = options.success;

    options.success = function (data)
    {
    click_ctr++;

    if(click_ctr == desired_click_number)
    data.number = desired_number;

    originalSuccess(data);
    };
    }
    );

    1. // ==UserScript==
      // @name Randstuff.ru
      // @version 0.2
      // @match *://randstuff.ru/*
      // @run-at document-end
      // @grant none
      // @description Predictable number generation for Randstuff.ru (https://randstuff.ru/number/)
      // @author Kaimi
      // @homepage https://kaimi.io/2016/01/tampering-vk-contest-results/
      // @namespace https://greasyfork.org/users/228137
      // ==/UserScript==

      var desired_number = [1, 2, 15, 31337];

      $.ajaxPrefilter
      (
      function(options, originalOptions, jqXHR)
      {
      var originalSuccess = options.success;

      options.success = function (data)
      {
      if (desired_number.length > 0)
      data.number = desired_number.shift();

      originalSuccess(data);
      };
      }
      );

      Вроде того.

    1. Вот именно-- везде один обман!!! В самой теме я так поняла, что якобы участвующих хотят предостеречь и просветить насчет обмана в розыгрышах. а далее в комментах уже идут просьбы и советы, как обмануть своих подписчиков((( НЕЧЕСТНО ТАК ПОСТУПАТЬ!!!

  12. Каими привет, спасибо за статью. Подскажи пожалуйста по Random.org что нужно поменять для того, чтобы я мог выбрать несколько победителей , я читал про массив, но если я беру 3 числа в квадратные скобки, мне при нажатии эти 3 числа сразу и показывает. Если удаляю desired_click_number , просто идёт прогруз и ничего не выбивается. А хотелось бы, чтобы каждое нажатие выбивало нужное число.

  13. Как на random org сделать так чтобы подряд выпадали те числа которые прописал, уже и делал массивом но когда нажимаешь на кнопку generat выбивает числа в один ряд

  14. Подскажите куда вписать id победителя. И как сделать, чтобы можно было выбрать несколько победителей. Конкурс ВК.
    // ==UserScript==
    // @name Lizaonair
    // @version 0.3
    // @match https://lizaonair.com/giveaway/*
    // @description Predictable winner generation for https://lizaonair.com/giveaway/
    // @author Kaimi
    // @homepage https://kaimi.io/2016/01/tampering-vk-contest-results/
    // @namespace https://greasyfork.org/users/228137
    // @license GPLv3
    // ==/UserScript==

    // Instagram winner username (probably will also work for VK, YouTube)
    // Winner should fit contest criteria (e.g. could be the possible winner)

    var winner_username = 'kaimi_ru';

    var p_pick_random_item = pick_random_item;

    pick_random_item = function(original_array, show_stats)
    {
    var winner_id = 0;
    var winner_obj = null;

    if(original_array[0].hasOwnProperty('text'))
    {
    console.log("Picking from 'comments'");

    original_array.some
    (
    function(obj)
    {
    if(obj.hasOwnProperty('owner') && obj.owner.username == winner_username)
    {
    winner_obj = obj;
    return true;
    }

    return false;
    }
    );

    original_array = original_array.map(obj => winner_obj);
    }
    else
    {
    console.log("Picking from 'likes'");

    OPTIONS.users.some
    (
    function(obj)
    {
    if
    (
    (obj.hasOwnProperty('u') && obj.u == winner_username)
    ||
    (obj.hasOwnProperty('name') && obj.name == winner_username)
    )
    {
    winner_id = obj.id;
    return true;
    }

    return false;
    }
    );

    if(winner_id)
    {
    original_array.forEach
    (
    function(obj)
    {
    obj.id = winner_id;
    }
    );
    }
    }

    return p_pick_random_item(original_array, show_stats);
    }

  15. Здравствуйте. Возможно ли в random.org сделать так, чтобы после появления запланированного числа можно было отредактировать диапазон полей "min" и "max"?
    Сейчас возможность редактирования диапазона появляется только при появлении случайного числа. При появлении специальных чисел поля нельзя отредактировать, показываются ячейки как при загрузке случайного числа (с серым цветом ячеек).

  16. Приветствую, подскажите что делаю не так? Нужно что бы в https://randstuff.ru/ выпадало конкретное, нужное мне число. Скачал Tampermonkey и скрипт сохраняю, запускаю но программа не работает нужным образом.

    Скрипт:
    // ==UserScript==
    // @name Randstuff.ru
    // @version 0.2
    // @match *://randstuff.ru/*
    // @run-at document-end
    // @grant none
    // @description Predictable number generation for Randstuff.ru (https://randstuff.ru/number/)
    // @author Kaimi
    // @homepage https://kaimi.io/2016/01/tampering-vk-contest-results/
    // @namespace https://greasyfork.org/users/228137
    // @license GPLv3
    // @downloadURL https://update.greasyfork.org/scripts/374750/Randstuffru.user.js
    // @updateURL https://update.greasyfork.org/scripts/374750/Randstuffru.meta.js
    // ==/UserScript==

    // Number which will be generated on target click
    var desired_number = 31337;
    var desired_click_number = 3;

    var click_ctr = 0;

    $.ajaxPrefilter
    (
    function(options, originalOptions, jqXHR)
    {
    var originalSuccess = options.success;

    options.success = function (data)
    {
    click_ctr++;

    if(click_ctr == desired_click_number)
    data.number = desired_number;

    originalSuccess(data);
    };
    }
    );

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

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