Введение
Привет хабровоинам.
Сегодня я напишу статью о небольшой уязвимости сервиса lingvist. Моя первая статья на Хабре, поэтому как принято писать, кхм… цитирую «помидорами просьба не кидать».
Все началось с того ( чавкая вставной челюстью ) когда я решил поизучать анг. язык.
Нашел данный сервис, зарегистрировался и все бы ничего, но сервис лингвист из-за незнания моего уровня прошаренности в анг.яз, без калибровочного теста начал давать ну совсем простые слова, вроде dog, i, you and other easy words.
Вообщем решил 100 — 200 слов вдруг вспомнилась поговорка:
«хороший программист — ленивый программист» ©.
А ведь действительно и началось.
Разведка html
Всякий раз, когда я вводил неправильное слово и нажимал на Enter всплывал полупрозрачный правильный вариант ответа.
Предположив что сразу после ввода неправильного (или правильного) слова,
ajax(ом) подгружается правильный ответ и вставляется в какой-нибудь placeholder,
начал инспектировать код:
Ну и ладно подумал я и решил что алгоритм будет такой:
- Эмулирую нажатие кнопки «проверка»
- Как только получаем правильное слово парсим его
- Спарсенное слово вставляем в input для ответа
- И снова эмулирует нажатие на отправку ответа
(все это в цикле через setTimeout)
Тем самым получаем много слов в словаре, а значит меньше элементарных, утомительных словечек и привет, увеличение словарного запаса!
Написание скрипта
По какой то причине JQuery на сайте не сработал и пришлось писать все на нативном js.
Сперва весь код:
setInterval(function(){
var selectorAnswer= document.getElementsByClassName("word-container")[0].childNodes;
selectorAnswerArr = [];
for (var i = 0; i < selectorAnswer.length; i++) {
var letter = selectorAnswer[i].innerHTML;
selectorAnswerArr.push(letter);
}
answerStr = selectorAnswerArr.join(",").replace(/,/g, "");
document.getElementsByClassName("answer-input")[0].value = answerStr;
document.getElementsByClassName("next")[0].click();
console.warn("Разгадали слово: " + answerStr );
}, 1000);
Краткий разбор строк:
- setInterval(function() {}, 1000)
Повторение вложенного кода раз в секунду. - var selectorAnswer= document.getElementsByClassName(«word-container»)[0].childNodes;
Селектор в который вложены span с буквами правильного слова - selectorAnswerArr = [];
Массив для будущего ответа. - for (var i = 0; i < selectorAnswer.length; i++) {})
цикл, который перебирает вложенные блоки в .word-container (то есть буквы правильного слова). - var letter = selectorAnswer[i].innerHTML;
узнаем буквы правильного слова - selectorAnswerArr.push(letter);
Толкаем правильные буквы в конец массива selectorAnswerArr - answerStr = selectorAnswerArr.join(",").replace(/,/g, "");
Собираем из нашего массива с буквами единое целое и убираем запятые через регулярку. - document.getElementsByClassName(«answer-input»)[0].value = answerStr;
Подставляем в значение input для ввода данных - document.getElementsByClassName(«next»)[0].click();
Эмулируем проверку нашего слова - console.warn(«Разгадали слово: » + answerStr );
Просто служебная информация в консоли
Take this! (надеюсь правильно написал).
P.S. Скрипт проверял только на браузере Chrome за кроссбраузерностью не гнался.
А теперь вишенка!
Как вы возможно вы заметили, в скрипте есть одна ошибка,
в начале скрипта должна выполняться эмуляция нажатия на кнопку,
что бы мы могли получить ответ от сервера в виде правильного слова.
Но на мое удивление скрипт отработал как надо!
Совпадение?
Полез в инспектор в раздел Network и тадааам:
Сайт во время первой загрузки на клиенте отдает все правильные ответы,
сделано это скорее всего с целью ускорить проверку ответа, другими словами мы можем
с 100% вероятность предугадать любое слово, такие дела!
Эй Хабр, надеюсь моя статья была полезна тебе, следующих статьях расскажу о
Если где то ошибся или у вас есть дополнения, пишите мне будет очень интересно почитать.
Автор: бро