Добрый день хацкеры! Есть сайт https://wot-leader.ru для любителей халявной голды WoT, после авторизации у вас голда падает от шапки до подвала. Есть такой код который работает с этой голдой и отправляет данные через Websocket Spoiler: JavaScript HTML: function rand(min, max) { return Math.random() * (max - min) + min; } function rand_int(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } function Coin(a_id, a_session, a_nominal, f, click_callback) { var that = this; this.id = a_id; this.session = a_session; this.nominal = a_nominal; this.zoom = 1.0; this.jq_obj; this.remove = function() { that.jq_obj.remove(); }; this.remove_smoothly = function() { that.jq_obj.stop(); that.jq_obj.animate({zoom: 0}, {duration: 800, always: that.remove}); }; this.activate = function() { var top = that.jq_obj.css('top'); var left = that.jq_obj.css('left'); var jq_hint = $('<div class=\"coin-hint coin-hint-normal\" style=\"top: '+ top +'; left: '+ left +';\">'+ that.nominal +'</div>'); $('body').append(jq_hint); that.remove_smoothly(); setTimeout(function() { jq_hint.remove(); }, 800); }; this.init = function() { this.zoom = 1;/*0.8 + this.nominal/(15/0.2);*/ this.jq_obj = $('<div class=\"'+ class_coin +'\" style=\"zoom: '+ this.zoom +'; left: '+ rand(5.0, 80.0) +'%; border-spacing: 0;\">'+ this.nominal +'</div>'); $('body').append(this.jq_obj); if (f) { this.jq_obj.css('left', '-'+ parseInt(-rand(360.0, 380.0)) +'px'); } else { this.jq_obj.animate({bottom: '-1%', left: rand(1.0, 85.0) + '%', borderSpacing: 101}, { step: function (now, fx) { if (fx.prop == 'borderSpacing') {/*alert(now+'');*/ /*$(this).css('bottom', (100-now) +'%');*/ } }, duration: rand_int(25000, 30000), easing: 'linear' }); } this.jq_obj.on('click touchstart tap', function() { that.sound_click(); click_callback(); }); }; this.sound_click = function() { var audio = new Audio(); audio.src = _cdn +'/Template/'+ _template +'/sound/coin_1.mp3'; audio.autoplay = false; audio.volume = 0.1; audio.play(); }; this.sound_fall = function() { var audio = new Audio(); audio.src = _cdn +'/Template/'+ _template +'/sound/coin_2.mp3'; audio.autoplay = false; audio.volume = 0.1; audio.play(); }; this.init(); } function Coin_Shared(a_nominal, a_nominal_view, a_num_all, click_callback) { var that = this; this.id = a_nominal; this.nominal = a_nominal; this.nominal_view = a_nominal_view; this.num_all = a_num_all; this.remains = a_num_all; this.zoom = 1.2; this.jq_obj; this.remove = function() { that.jq_obj.remove(); }; this.remove_smoothly = function() { that.jq_obj.stop(); that.jq_obj.animate({zoom: 0}, {duration: 800, always: that.remove}); }; this.set_remains = function(remains) { that.jq_obj.children('.remains').html(remains +' / '+ that.num_all); if (remains < 1) { that.remove_smoothly(); } }; this.activate = function(hint_text) { var top = that.jq_obj.css('top'); var left = that.jq_obj.css('left'); var jq_hint = $('<div class=\"coin-hint\" style=\"top: '+ top +'; left: '+ left +';\">'+ hint_text +'</div>'); $('body').append(jq_hint); setTimeout(function () { jq_hint.remove(); }, 1000); }; this.init = function() { this.zoom = 1.2;/*0.8 + this.nominal/(15/0.2);*/ this.jq_obj = $('<div class=\"'+ class_coin +'\" style=\"zoom: '+ this.zoom +'; left: '+ rand(5.0, 80.0) +'%; border-spacing: 0;\">'+ this.nominal_view +'<div class=\"remains\"></div></div>'); $('body').append(this.jq_obj); that.set_remains(that.num_all); this.jq_obj.animate({bottom: '-1%', left: rand(1.0, 85.0)+'%', borderSpacing: 101}, { step: function(now, fx) { if (fx.prop == 'borderSpacing') {/*alert(now+'');*/ /*$(this).css('bottom', (100-now) +'%');*/ } }, duration: rand_int(25000, 30000), easing: 'linear' }); this.jq_obj.on('click touchstart tap', function() { that.sound_click(); click_callback(); }); }; this.sound_click = function() { var audio = new Audio(); audio.src = _cdn +'/Template/'+ _template +'/sound/coin_1.mp3'; audio.autoplay = false; audio.volume = 0.1; audio.play(); }; this.sound_fall = function() { var audio = new Audio(); audio.src = _cdn +'/Template/'+ _template +'/sound/coin_2.mp3'; audio.autoplay = false; audio.volume = 0.1; audio.play(); }; this.init(); } function Coins_Core() { var coins = []; var socket; var session_id = ''; var id_c = 1; var interval_check_session; var is_opened_window_rating_adv = false; var is_bye = false; var response; var api_url = 'wss://ws-coin.wot-leader.ru:8443/'; var prompt = window.prompt; var alert = window.alert; function request_api(action, data) { data = data || {}; data.action = action; data.session_id = session_id; return $.ajax({ url: './coins_api.php', dataType: 'json', data: data, type: 'POST' }); } function send_api(action, data) { data = data || {}; data.action = action; var message = JSON.stringify(data); console.log('Отправка: '+ message); return socket.send(message); } function start_session() { if (session_id != '') { send_api('auth', {session_id: session_id}); return; } var req = request_api('init'); req.done(function(response) { if (!response.success) { setTimeout(start_session, 1500); return; } if (response.is_banned) { return; } session_id = response.session_id; $.cookie('coin_session', session_id); interval_check_session = setInterval(check_session, 1000); send_api('auth', {session_id: session_id}); setInterval(function() { var coin = { id: rand(1.9464, 999999.954), nominal: rand_int(1, 11) / 100.0, duration: 10, f: true }; add_new_coin(coin); }, 10000); }); req.fail(function() { setTimeout(start_session, 1500); }); } function check_session() { if ($.cookie('coin_session') != session_id) { clear(); } } function try_open_modal_rating_adv() { if (current_modal !== null) { if (current_modal.html() == $('#modal_game').html() || current_modal.html() == $('#modal_game_win').html()) { setTimeout(try_open_modal_rating_adv, 500); return; } } is_opened_window_rating_adv = false; if (current_modal == $('#modal_rating_adv')) { return; } open_modal('modal_rating_adv'); var adv_blocks = $('*[id^=\"adv_block_\"]'); adv_blocks.hide(); var adv_block = adv_blocks.get(Math.round(Math.random()*5646467434) % adv_blocks.length); $(adv_block).show(); } function open_modal_rating_adv() { if (is_opened_window_rating_adv) { return; } is_opened_window_rating_adv = true; try_open_modal_rating_adv(); } function clear() { for(var i in coins) { coins[i].remove(); } coins = []; clearInterval(interval_check_session); } function exclude_coin(id) { var new_coins = []; for(var i in coins) { if (coins[i].id == id) { continue; } new_coins.push(coins[i]); } coins = new_coins; } function coin_by_id(id) { for(var i in coins) { if (coins[i].id != id) { continue; } return coins[i]; } return null; } function add_new_coin(a_coin) { var coin_id = a_coin.id; var nominal = a_coin.nominal; var duration = a_coin.duration; var f = a_coin.f; var coin = new Coin(coin_id, session_id, nominal, f, function () { if (f) { var req = request_api('clicker_detect'); req.done(function(response) {}); } else { send_api('coin', {coin_id: coin_id}); } }); coins.push(coin); if (duration > 0) { setTimeout(function() { coin.remove_smoothly(); setTimeout(function() { exclude_coin(coin_id); }, 1000); }, (duration-1)*1000); } } function restoreCoins_action() { new_coins_action(); } function new_coins_action() { for (var i in response.coins) { add_new_coin(response.coins[i]); } } function captcha_action() { var text = 'Чтобы вы могли собирать монеты, пожалуйста, ответьте на простой вопрос:\n '+ response.captcha.question +' = ?'; if (response.attempted) { text = 'Вы ввели неверный ответ, попробуйте еще раз:\n '+ response.captcha.question +' = ?'; } var code = prompt(text); if (!code) { alert('Увы, вы не верно ответили на проверочное значение или закрыли окно с проверочным значением. Пожалуйста, обновите страницу.'); clear(); socket.close(); } else { send_api('captcha', {captcha: code}); } } function activate_coin_action() { var coin = coin_by_id(response.coin_id); if (coin !== null) { coin.activate(); exclude_coin(response.coin_id); set_balance(balance + parseFloat(response.coin_nominal)); } } function rating_adv_action() { open_modal_rating_adv(); } function shared_coin() { var nominal = response.nominal; var nominal_view = response.nominal_view; var num = response.num; var coin = new Coin_Shared(nominal, nominal_view, num, function () { send_api('shared_coin', {nominal: nominal}); }); coins.push(coin); } function shared_coin_activate() { var remains = response.remains; var hint = response.hint; var nominal = response.nominal; var coin = coin_by_id(nominal); if (coin !== null) { coin.activate(hint); if (response.is_i) { set_balance(balance + parseFloat(response.nominal)); } coin.set_remains(remains); if (remains < 1) { exclude_coin(nominal); } } } function socket_init() { socket.onopen = function() { console.log('Соединение установлено.'); start_session(); }; socket.onclose = function(event) { console.log('Код: ' + event.code + ' причина: ' + event.reason); if (event.wasClean) { clear(); return; } clear(); setTimeout(function() { socket = new WebSocket(api_url); socket_init(); }, 1000); }; socket.onmessage = function(event) { console.log('Получены данные ' + event.data); if (event.data == 'Bye') { return; } else if (event.data == 'Exceeding') { alert('Превышено максимальное количество человек на сайте. Зайдите позже.'); return; } response = JSON.parse(event.data); if (response.action == 'restoreCoins') { restoreCoins_action(); } else if (response.action == 'coins') { new_coins_action(); } else if (response.action == 'captcha') { captcha_action(); } else if (response.action == 'activate_coin') { activate_coin_action(); } else if (response.action == 'rating_adv') { rating_adv_action(); } else if (response.action == 'shared_coin') { shared_coin(); } else if (response.action == 'shared_coin_activate') { shared_coin_activate(); } }; socket.onerror = function(error) { console.log('Ошибка ' + error.message); }; } this.init = function() { if (window.is_logged) { socket = new WebSocket(api_url); socket_init(); } else { setTimeout(function() { var duration = 180; var coin = new Coin(1, '', '8.00', false, function () { open_modal('modal_auth_adv'); coin.remove_smoothly(); }); setTimeout(function() { coin.remove_smoothly(); }, 600 * 1000); }, 300); } }; } $(function() { var coins_core = new Coins_Core(); coins_core.init(); }); Класс коин можно и самому вызвать через консоль new Coin(); HTML: new Coin(978623270, "f9f6de2325573f122033e229625d1d72", "1.01", false, function () { send_api('coin', {coin_id: 978623270}); }); Но дело в том, что функция send_api() находится внутри функции Coins_Core() и соответственно она не вызовется. Вопрос в том, как это можно реализовать? P.S. Можно было бы оборвать текущую сессию с вебсокетом, и просто через консоль вставить весь код заново, с исправленной функцией генерирования Голды, но переменная socket так же находится в функции Coins_Core() и всё в пустую. P.P.S. Сама задача сделать эту инъекцию и получать больше голды, но так, чтобы не сильно палевно было. К примеру в данный момент одна монета рандом от 0.01 до 0.04 вот исправить функцию генерирования и или же умудриться создать NEW COIN и отправить запрос со своим числом.
Если весь этот гемор нужен только для отправки запроса, то проще пустить траф через проксю и менять его на лету. Либо отловить легитимный запрос, а потом меняя значения, вручную, посылать сколько угодно раз.
Через расширения хрома ты можешь вставлять на сайты свои скрипты, да и есть специальные расширения что бы писать пользовательские скрипты... гугли userjs Так как функция на сайте объявлена глобально - ты можешь её ПОЛНОСТЬЮ заменить. window.Coins_Core = function() { ... }. Или через тот же userJS ты сам можешь создать websocket нужный тебе. И еще веб сокеты часто кроссдоменные поэтому ты можешь реализовать вообще на любом ЯП в любом месте работу с ними. Там алгоритм какой 1 получить идентификатор сессии отправляешь POST запрос action=init&session_id= на https://wot-leader.ru/coins_api.php тебе в json вернет session_id 2 открываешь вебсокет и шлешь acttion:auth,session_id:session_id 3 что бы плюшку сгенерить шлешь в сокет action:coin, coin_id: rand(1.9464, 999999.954) Ну а там дальше смотри по коду че там слать что бы задать ей наминал и по ней кликнуть и повторяй в цикле. https://github.com/Garik-/helpers.js - там есть оберточка ООП над вебсокетами.
К сожалению не работает. так как id скорее всего не генирируется на клиенте. Вот что отправляет их скрипт Отправка: {"coin_id":1013169638,"action":"coin"} Получены данные {"action":"activate_coin","coin_id":1013169638,"coin_nominal":0.01} Вот мной сгенерированный Отправка: {"coin_id":783339.7058598413,"action":"coin"} Получены данные Bye Bye это при попытке сбора монеты.
Мне не нравится что id дробный... попробуй просто 9 циферок юзать рандомных. Или продублировать иды которые слал сайт. Просто посмотреть что будет А ещё если ты мог заметить там есть строчка после авторизации через POST $.cookie('coin_session', session_id); Точно не знаю участвуют куки в websocket запросах или нет, но чем черт не шутит
Сессия шлётся 1 раз при авторизации. Т.е. я через консоль делаю повторное подключение к вебсокету используя текущую сессию, прохожу авторизацию и ответ от сервера никакой - т.е. ошибки нет, следующим шагом генерирую и отправляю плюшку и уже тут получаю ошибку от сервера,