Во многих социальных сетях, в том числе в ВКонтакте, с некоторых пор стало проводиться множество конкурсов с ценными призами. Речь пойдет о подделке результатов с точки зрения организатора, а конкурсы - те, в которых победитель определяется случайным образом из списка участников.
Итак, существует множество сервисов, которые помогают в проведении сферического конкурса, а доказательством зачастую является записанное видео или прямой эфир, в процессе которого происходит выбор победителя. Давайте рассмотрим, как можно организовать тривиальную подмену результатов, ничем себя не выдав. В качестве примера я рассмотрю вариант с использованием random.org (тот случай, когда организатор генерирует последовательно несколько случайных чисел, чтобы определить страницу и порядковый номер участника на странице), а также вариант с использованием Random.app.
Для начала давайте определимся, как вообще можно провести незаметную подмену в прямом эфире. Самое первое, что приходит в голову: перехватить и модифицировать запросы с помощью промежуточного прокси-сервера (например, Fiddler или Charles), модифицировать результат непосредственно в браузере (например, с помощью Greasemonkey или Tampermonkey), сделать визуальную копию необходимого ресурса на локальном сервере и заворачивать запросы на него с помощью hosts-файла или своего DNS-сервера, и так далее. В конце концов, можно что угодно "нарисовать", если речь идет о видеозаписи проведения конкурса. Остановимся на варианте с модификацией результата в браузере с помощью Tampermonkey или Greasemonkey. На мой взгляд этот вариант наиболее простой для реализации и понимания.
Берем Google Chrome и ставим в него Tampermonkey (есть в Chrome Web Store). В "я без понятия, как это место называется" панели появится новая иконка.
Приступим, для начала random.org. Заходим на сайт и видим в правой части True Random Number Generator, который обычно и используется.
После беглого изучения мы видим, что этот элемент представляет собой iframe, который загружается по ссылке вида:
1 |
https://www.random.org/widgets/integers/iframe.php?title=True+Random+Number+Generator&buttontxt=Generate&width=160&height=200&border=on&bgcolor=%23FFFFFF&txtcolor=%23777777&altbgcolor=%23CCCCFF&alttxtcolor=%23000000&defaultmin=1&defaultmax=100&fixed=off |
Пройдя по ссылке мы можем увидеть, что основная логика реализована в файле iframe.js, после изучения логики становится очевидно, что при нажатии кнопки Generate шлется http-запрос к random.org с желаемым диапазоном, которые возвращает случайное число из диапазона и выводится с помощью вызова функции printNumber из iframe.js. Давайте реализуем простую подмену результата.
Нажмем по вышеупомянутой иконке Tampermonkey и выберем пункт Add a new script. Откроется редактор, куда вы можете сразу скопировать данный скрипт (не забыв после этого нажать кнопку Save):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
// ==UserScript== // Название, версия скрипта и URL, в контексте которого скрипт будет автоматически запускаться // @name Random.org // @version 0.1 // @match https://www.random.org/* // ==/UserScript== // Число, которым мы хотим заменить результат var desired_number = 31337; // На каком по счету нажатии произвести замену var desired_click_number = 3; var click_ctr = 0; // Проверяем, что функция printNumber определена if (typeof printNumber != "undefined") { // Сохраняем printNumber под другим именем и переопределяем её var origPrintNumber = printNumber; printNumber = function() { // Ведем учет кол-ва вызовов функции и подменяем результат на нужном по счету click_ctr++; if (click_ctr == desired_click_number) document.getElementById("true-random-integer-generator-result").innerHTML = desired_number; else origPrintNumber(); } }; |
Как видите - скрипт достаточно простой. В текущем варианте, на 3 по счету нажатии кнопки Generate, мы увидим результат 31337, независимо от заданного диапазона. Чтобы сбросить счетчик нажатий, достаточно перезагрузить страницу в браузере.
Теперь давайте проведем беглый анализ Random.app.
Мы имеем дело с приложением для ВКонтакте, которое тоже встраивается с помощью iframe. Приложение использует VK API и не взаимодействует с социальной сетью для получения списка возможных победителей. Победитель выбирается случайным образом простым вызовом Math.random. С основной логикой работы Random.app можно ознакомиться, пролистав содержимое следующих скриптов: main.js, random.models.js, random.views.js. Приведу небольшие фрагменты кода, которые отвечают за интересующие нас действия:
main.js
1 2 3 4 5 6 |
$(document).on('click', '.roll-roulette', function () { // console.log(usersArray); var id = Math.floor((Math.random() * usersArray.length)); view.setWinner(usersArray[id]); view.resizeWindow(); }) |
random.view.js
1 2 3 4 5 6 |
setWinner: function(user){ $('.winner .photo a').attr('href','http://vk.com/id'+user.uid); $('.winner .photo img').attr('src',user.photo_big); $('.winner .name').html(user.first_name + ' '+ user.last_name); this.resizeWindow(); } |
Мы видим, что на элемент с классом .roll-roulette (кнопка Выбрать победителя) вешается обработчик, который выбирает случайного пользователя из заранее сформированного списка и вызывает функцию setWinner, которая отображает победителя. Что ж, давайте сделаем простой скрипт, скопировав часть логики с сайта автора:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
// ==UserScript== // @name Random.app // @version 0.1 // @match *://pliashkou.com/* // Воспользуемся JQuery для упрощения некоторых действий // @require https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js // ==/UserScript== // ID победителя var winnerUid = [75292250]; // Добавляем свой обработчик для кнопки Выбрать победителя $(document).on ( 'click', '.roll-roulette', function () { // Воспользуемся методами Random.app для получения необходимых данных от VKontakte // По сути мы просто получаем фамилию, имя и адрес фотографии для отображения var view = new CommonView(); var users = new Users(); users.options.from = 0; users.options.limit = 1; users.get ( { uids: winnerUid, fields: 'uid, first_name, last_name, photo_big' }, // Выводим победителя, как только получим данные от VK API function (users) { view.setWinner(users[0]); view.resizeWindow(); } ); } ) |
Всё опять-таки крайне тривиально, теперь при нажатии кнопки мы всегда будем получать человека с желаемым ID в качестве победителя. Естественно, никто не мешает добавить дополнительной логики в скрипт, чтобы выигрывали не только "избранные", но кому это надо...
Остается еще один простой момент: по-умолчанию в Chrome видна кнопка расширения Tampermonkey и зрители могут что-то заподозрить - не вопрос, нажимаем правой клавишей по ней и выбираем пункт Hide button.
Подведем итоги. Я разобрал часто встречающиеся примеры, однако, ими дело не ограничивается. Еще существуют ресурсы, которые после проведения розыгрыша предоставляют ссылку на результат, чтобы пользователи могли пройти по ней и убедиться что всё честно, но, вы же понимаете, что ресурсом владеют простые люди, а договориться можно с кем угодно. Хотя, пожалуй, можно верить таким ссылкам с random.org (вроде бы доступно только для владельцев платных аккаунтов), но другие ресурсы под большим вопросом, ведь кто мешает, например, мне создать очередной сайт для проведения розыгрышей, раскрутить его и выиграть там, где мне это интересно.
Update (29.01.2017)
Обновленная версия скрипта для Random.app:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
// ==UserScript== // @name Random.app // @version 0.2 // @match *://pliashkou.com/* // Воспользуемся JQuery для упрощения некоторых действий // @require https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js // ==/UserScript== // ID победителя var winnerUid = [75292250]; var f_ptr = VK.api; vk_api = function(method, options, callback) { if(method == 'getProfiles') { // Если запрашивается информация об одном победителе if(options.uids.indexOf(',') == -1) options.uids = winnerUid.shift(); } return f_ptr(method, options, callback); }; // Добавляем свой обработчик для кнопки Выбрать победителя $(document).on ( 'mouseover', '.btn-default', function () { // Переопределяем метод VK.api VK.api = vk_api; } ); |
Update (04.03.2018)
Скрипт для Randstuff.ru:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
// ==UserScript== // @name Randstuff.ru // @version 0.1 // @match http://randstuff.ru/* // @run-at document-end // @grant none // ==/UserScript== 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); }; } ); |
Скрипт для Randomizer:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
// ==UserScript== // @name Randomizer // @version 0.1 // @match *://im-brand.ru/* // ==/UserScript== var bReplacePhoto = false; var winnersList = [ ['Максим Антонов', 'https://pp.userapi.com/c638823/v638823253/43120/RuiiVVlULKc.jpg'], ['Петр Андреев', 'https://pp.userapi.com/c638823/v638823253/43120/RuiiVVlULKc.jpg'], ['Илья Новиков', 'https://pp.userapi.com/c638823/v638823253/43120/RuiiVVlULKc.jpg'] ]; var getWinnerHTMLPtr = getWinnerHTML; getWinnerHTML = function(winner) { if(winnersList.length > 0) { var currentWinner = winnersList.shift(); var userName = currentWinner[0].split(" "); winner.first_name = userName[0]; winner.last_name = userName[1]; if(bReplacePhoto) winner.photo_50 = currentWinner[1]; } return getWinnerHTMLPtr(winner); }; |
Update (04.06.2018)
Скрипт для Random.app:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
// ==UserScript== // @name Random.app // @version 0.3 // @match https://s3.eu-central-1.amazonaws.com/randomapp* // @require https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js // ==/UserScript== // ID победителя var winnerUid = [75292250]; var f_ptr = VK.api; vk_api = function(method, options, callback) { if(method == 'getProfiles') { if(options.uids.indexOf(',') == -1) options.uids = winnerUid.shift(); } return f_ptr(method, options, callback); }; $(document).on ( 'mouseover', '.btn-default', function () { VK.api = vk_api; } ); |
Скрипт для Randomizer:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
// ==UserScript== // @name Randomizer // @version 0.2 // @match *://shilov.app/* // ==/UserScript== var bReplacePhoto = false; var winnersList = [ ['Максим Антонов', 'https://pp.userapi.com/c638823/v638823253/43120/RuiiVVlULKc.jpg'], ['Петр Андреев', 'https://pp.userapi.com/c638823/v638823253/43120/RuiiVVlULKc.jpg'], ['Илья Новиков', 'https://pp.userapi.com/c638823/v638823253/43120/RuiiVVlULKc.jpg'] ]; var getWinnerHTMLPtr = getWinnerHTML; getWinnerHTML = function(winner) { if(winnersList.length > 0) { var currentWinner = winnersList.shift(); var userName = currentWinner[0].split(" "); winner.first_name = userName[0]; winner.last_name = userName[1]; if(bReplacePhoto) winner.photo_50 = currentWinner[1]; } return getWinnerHTMLPtr(winner); }; |
Скрипт для Randstuff.ru:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
// ==UserScript== // @name Randstuff.ru // @version 0.2 // @match *://randstuff.ru/* // @run-at document-end // @grant none // ==/UserScript== 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); }; } ); |
Update (24.11.2018): Решил выкладывать скрипты на сторонний сервис: https://greasyfork.org/en/users/228137-kaimi (доступны актуальные версии для сервисов Random.app, Random.org и Randstuff.ru).
тоже надо
Здравствуйте. Тоже очень ждем скрипта , думаю что там не сложно поправить , всю суть что сделали опишу.
Там где прежде было приложение было полностью обновлено, а старую версию с которой мы работали перенесли на новую ссылку https://vk.com/app6108296
Обновлено на Greasyfork
Все круто , олично работает
Как выиграть вот на этом сайте lizaonair.com, будет ли сложно написать к нему похожий скрипт?)
Здравствуйте, меня интересует и нужна помощь, проведён конкурс и хочется узнать куда смотреть, где произошёл обман ? Было в контакте с рандомом .
Вот ссылка https://vk.com/video-104233048_456239074?api_access_key=a38d309620c7f2dde4
Сложно сказать, в принципе, если скрыть плагин, чтобы он не отображался в окне браузера, то не определишь.
Да и скрипты для tampermonkey - это не единственный способ.
Спасибо за статью! Подскажите, пожалуйста, что нужно дописать в скрипте для рандом орг, чтобы было одновременно 5 чисел на подмену. Заранее спасибо!
Подряд или случайное из 5 чисел бралось?
Можно убрать проверку счетчика нажатий, сделать desired_number массивом и брать из него подряд или в случайном порядке числа.
Подскажи пожалуйста, как вывести 3 нужных цифр, чтобы не перезагружать каждый раз страницу? То есть в примере в скрипте прописано 31117, я ввел нужную сумму(202) оно выходит первым кликом, остальные наугад. Как сделать так, чтобы все 3 клика были нужными мне, то есть должно выдать такой порядок: 202, 31, 582
Сделать массив из нужных чисел, далее при каждом клике не проверять номер, а просто доставать по очереди числа из массива, пока массив не пустой, если массив закончился, то вызывать оригинальный рандом.
Можно вопрос? как сделать чтобы был не один человек, а 2 и больше?
Переписать код соответствующим образом.
https://learn.javascript.ru/
Здравствуйте. Есть актуальная ссылка для скачивания скприпта? На том сайте выдаёт ошибку 404
Да вроде https://greasyfork.org/en/users/228137-kaimi работает
Каими, огромное спасибо за код, очень выручил. Но назрел вопрос, как переписать его, что б он подряд выбирал нужных победителей.
не работает эта ссылка
Здравствуйте, подскажите, пожалуйста как это сделать? Чтобы desired_number был массивом..
Взять в квадратные скобки, перечислить значения через запятую, элемент получать через shift.
Понял, спасибо, а еще такой вопрос: " if (click_ctr == desired_click_number)"
Мне нужно с этим что-то делать? Т.к я убираю же этот самый счетчик нажатий..
Можно убрать, если предполагается с первого значения выдавать то, что требуется. Можно какую-то логику описать
Здравствуйте, подскажите пожалуйста как прописать массив для desired_number
Квадратные скобки использовать, в них через запятую элементы. Извлекать элемент через метод shift. И видимо убрать или модифицировать проверку на номер клика по счету.
Простите,а можно для аникейщиков))))😀🙏
Привет, всячески испробовать этот метод, но никак не выходит, можешь прописать его здесь еще раз, чтобы при каждой нажатии generate, выходило то число которое нам необходимо, буду очень благодарен.
А можно подделать результаты если ты участник?
Нет, разве что написать альтернативное приложение, сделать его популярным и себе подкручивать.
Ну вот выдал мне рондом орг цифры, а как экспортировать репостнувших и пронумеровать ?
¯\_(ツ)_/¯
Подскажите можно ли подделать нужное нам число на https://randstuff.ru/number/ Очень надо!!!!
https://greasyfork.org/en/scripts/374750-randstuff-ru
Наверное еще работает.
Не получаться установить скрипт. Подскажите плиз
Да вроде все просто, зайти на сайт greasyfork, нажать установить
Здравствуйте как сделать чтобы второй и третий выграл пожалуйста подскажите
Добрый день. Как уличить группу в фальсификации конкурса?
Добрый день, разве что убедить их использовать какой-то сервис, который предоставляет ссылку с результатом проведения.
Т.е. чтобы было не только скриншот/видео, а еще ссылка на результаты.
Что-то вроде https://randompromo.ru/ , но я не знаток этих сервисов, не пользовался ими.
CAN YOU MAKE A SCRIPT TO FAKE THE RESULTS ON LIZAONAIR WEBSITE?
Привет. Можешь дать скрипт для сайта рандомазер.рф?
Здравсвуйте! можно ли сделать так чтоб определенный человек выиграл по нику, чтоб рандомайзер показал победителе его ник?
Визуально можно сделать что угодно.
а можете за деньги прям сейчас сделать? у нас день конкурса просто..
Если речь о https://vk.com/app4938347, то https://greasyfork.org/en/scripts/426801-randomizer
С аватаркой и именем понятно, а как ссылку то подставить на нужного пользователя? Ссылка там действительная остаётся, а не подставленная.
Если речь про Random.app, то там используется метод users.get, если ссылка берется из данных, которые он возвращает, то просто заменять значение параметра в возвращаемом объекте.
Скажите но при работе скрипта число указывается без текса снизу (
Min: 1, Max: 100
2021-06-10 15:07:42 UTC - вот этот текст можно также записать в скрипт. ?
Актуальная версия на greasyfork
здравствуйте! после первого нажатия кнопка "generate" перестает быть активной. Мне кажется это палевно) могу я как-нибудь поменять Ваш скрипт, чтобы это убрать.)) спасибо заранее!
Добрый день, речь о последней версии с greasyfork?
Да. В последней версии кнопка Generate неактивна становится. Исправьте, пожалуйста
Здравствуйте! После вывода итогов в последней версии, кнопка"generate" перестает быть активной. Как это изменить?
Добрый день, версия на greasyfork обновлена, должно работать
привет) не нашел скрипт для него https://vk.com/app6108296 на greasyfork искал не нашел
https://greasyfork.org/en/users/228137-kaimi первый в списке скрипт должен работать, если ничего не поменялось
после выполнения кнопка "generate" не активна
добрый день подскажите как сделать несколько мест победителей?
по этому вашему коду написал, все работает. но хотелось бы сделать несколько победителей не одного.
// ==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);
};
}
);
Вроде того.
как много людей подделывает конкурсы, что даже участвовать в них не охота))
Вот именно-- везде один обман!!! В самой теме я так поняла, что якобы участвующих хотят предостеречь и просветить насчет обмана в розыгрышах. а далее в комментах уже идут просьбы и советы, как обмануть своих подписчиков((( НЕЧЕСТНО ТАК ПОСТУПАТЬ!!!
Каими привет, спасибо за статью. Подскажи пожалуйста по Random.org что нужно поменять для того, чтобы я мог выбрать несколько победителей , я читал про массив, но если я беру 3 числа в квадратные скобки, мне при нажатии эти 3 числа сразу и показывает. Если удаляю desired_click_number , просто идёт прогруз и ничего не выбивается. А хотелось бы, чтобы каждое нажатие выбивало нужное число.
https://vk.com/wall-199519146_25974 Можно ли узнать кто победил в этом конкурсе?
Как на random org сделать так чтобы подряд выпадали те числа которые прописал, уже и делал массивом но когда нажимаешь на кнопку generat выбивает числа в один ряд
Что-нибудь типа https://greasyfork.org/en/scripts/438647-random-org/code
Подскажите куда вписать 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);
}
Здравствуйте. Возможно ли в random.org сделать так, чтобы после появления запланированного числа можно было отредактировать диапазон полей "min" и "max"?
Сейчас возможность редактирования диапазона появляется только при появлении случайного числа. При появлении специальных чисел поля нельзя отредактировать, показываются ячейки как при загрузке случайного числа (с серым цветом ячеек).
Привет . Сделай пожалуйста скрипт на новое приложение ВК https://vk.com/app5455796?cid=0&queue=1§ion_type=&sid=0
Приветствую, подскажите что делаю не так? Нужно что бы в 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);
};
}
);
В Firefox все работает