Я специально не пишу ссылки на те тесты, которые как бы "взламываю", просто чтобы не появилось слишком много желающих этим воспользоваться из-за чего разработчики могут заметить что-то странное и поменять код, в котором снова придется разбираться. Предыдущая небольшая заметка здесь. В этой заметке речь идет о другом сайте с тестами по промбезопасноти. Как и в прошлый раз полезно поизучать как обрабатываются тесты в панели разработчика вашего браузера. Для этого отвечаю на тест и жму проверить, и в ответ мне присылается уже сформированный документ где зеленым цветом помечаются правильные ответы:
Вся магия скрывается во вкладке полезная нагрузка, где четко видно что после нажатия на кнопку проверить, на сервер посылается POST запрос такого вида:
В нем 10 вопросов, каждый имеет свой идентификатор, и дается номер ответа после знака равно. Запрос завершается номером итерации, который для всех 5, номером билета, и номером теста, который можно получить из адресной строки. Идея хака заключается в том чтобы открыть билет, отправить запрос, получить документ, распознать в нем правильные ответы, которые подсвечиваются зеленым, и пометить звездочкой эти верные ответы на странице теста. После этого можно спокойно выбирать все ответы со звездочкой, и получить 100% результат (но это не точно, т.к. имеются все же нюансы, когда на несколько вопросо дается несколько вариантов ответов) .
Начнем по порядку:
let array;	
let str ='';
let ans = [];
lctn = location.href.replace(location.origin,'');
bilnum = lctn.replace(/(.+)bil=(\d+)(.+)/gm, '$2');
for (let i=0;i<document.getElementsByTagName('i').length;i++) {	
	qnum = i+1;
	qval = document.getElementsByName('q'+qnum )[0].value;
	str = str + 'q' + qnum + '=' + qval + '&' + qval + '=1&';
}	
str = str + 'Width=&'+ lctn.replace('/?iter=4', 'iter=5');	
console.log(str);	
Из адресной строки получаем номер билета, а дальше проходимся по странице и выбираем идентификаторы вопросов, которые находятся в элементах с типа <i> и с именем q1, q2 и т.д до 10, - это все видно что формирется через цикл. При этом в переменную str записывается итоговая строка запроса, которую мы видели на скрине выше. При этом запросе нам совсем не важно какой номер ответа посылать, и везде посылаем первый ответ
Следующим шагом посыллаем POST запрос со сгенерированной строкой:
var xhr = new XMLHttpRequest();	
var body = str;		
xhr.open('POST', lctn, true);	
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.responseType = 'document';
xhr.send(body);	
xhr.onload = function() {
  let responseObj = xhr.response;
  console.log(responseObj); 
array = responseObj.getElementsByClassName('f_sm');
При этом получаем документ, а в нем ищем элементы класса f_sm. Проходимся по массиву этих элементов и отправляем в массив правильных ответов те (причем именно текст ответа, целиком), что подсвечиваются зеленым цветом. Причем на сайте очень интересно сделано что зеленый цвет всегда имеет разный оттенок, именно поэтому в системе RGB сравнивается количество красного и зеленого цветов в итоговом ответе, чтобы понять что это наш ответ
for (let i=0;i<array.length;i++){
	if (array[i].style.color.includes('rgb')) {
		let arr2 = array[i].style.color.match(/(\d+)/gm);
		if (parseInt(arr2[0]) < 100 & parseInt(arr2[1]) > 150) {
			ans.push(array[i].innerHTML.replaceAll(/<\/?b>/g,''));
		}
	}
}
И да, если у нас ответ помечен жирным (это значит что мы угадали, и первый вариант ответа, который выбирали и есть верный вариант) то мы убираем жирность с помощью регулярного выражения, которое отсекает все html теги жирности
ну и в конце просто ищем ответы на нашей странице которые соответствуют тем что находятся в массиве ans, и добавляем им * 
for (let j=0;j<ans.length;j++) {
	document.body.innerHTML = document.body.innerHTML.replace(ans[j],' * '+ans[j]);
}};
Вот и все. В этот раз без готового букмарклета) но сделать его не проблема, как мне кажется.
 
Здравствуйте, вы можете мне помочь во взломе одного сайта, если да то как с вами можно связаться?
ОтветитьУдалитьДоброго дня. познавательная статья. Сможете подсказать в похожей задаче? sergo5 {} mail.ru
ОтветитьУдалить