Задача предполагает 2 способа решения:
1) аналитический;
2) анализ исходного кода (reverse-engineering).
Способ 1.
На открывшейся web-странице есть следующие активные поля (рисунок 5.2-1):
- логин (1);
- пароль (2);
- ссылка «Помнишь меня?» (3);
- ссылка «Забыли код?» (4).
Рисунок 5.2-1 Внешний вид web-страницы
Известно, что логин состоит только из букв, пароль состоит только из цифр. Длина логина и пароля должны совпадать.
Нажав на ссылку «Помнишь меня?», страница выдает сообщение:
mhjyzko
Нажав на ссылку «Забыли код?», страница выдает сообщение:
thequickbrownfxjmpsvlazydg
01234567890123456789012345
Можно заметить, что в первой строке содержатся все символы английского алфавита без повторений (26 символов). Каждому символу соответствует свой номер из нижней строки: t–0, h–1, e–2, … q–5.
Можно предположить, что это не случайность, и не просто так. Поэтому можно попробовать взять сообщение mhjyzko, использовать его как логин, а в качестве пароля подобрать цифры из второй подсказки «Забыли код?»:
m–6, h–1, j–5, y–3, z–2, k–7, o–0.
Вводим следующие данные:
логин – mhjyzko,
пароль – 6153270
В результате на странице отобразится код: ROCKET (рисунок 5.2-2).
Рисунок 5.2-2 – Содержимое web-страницы после правильно введенных логина и пароля
Способ 2.
Проанализировав код страницы можно увидеть, что к странице подключены следующие JavaScript-файлы:
< script src="script/proof.js">
< script src="script/script.js">
< script src="js/script.js">
Остальные файлы относятся к платформе для корректного отображения объектов.
Рассмотрим содержимое файла js/script.js. В этом файле устанавливаются обработчики событий click на объекты web-страницы:
- при нажатии на ссылку «Помнишь меня?» выводится сообщение с результатом выполнения функции forgetCode();
- при нажатии на ссылку «Забыли код?» выводится сообщение с выражением getBaseString()+'\n01234567890123456789012345';
- при нажатии на кнопку «Войти» вызывается функция myfunc(), которая описана в этом же файле.
Интерес вызывает именно функция myfunc(). Рассмотрим её подробнее (листинг 5.2-1).
Листинг 5.2-1 – Содержимое функции myfunc()
1 |
function myfunc() { |
2 |
let code = ''; |
3 |
if (username_form.value && passwd_form.value) |
4 |
code = getCode(username_form.value, passwd_form.value); |
5 |
if (code && code.length > 0) |
6 |
code_label.innerText = code; |
7 |
else |
8 |
code_label.innerText = 'ВОЙТИ'; |
9 |
} |
В строке 3 проверяется на непустые значения полей логин и пароль, после чего вызывается функция getCode(). Результат функции отображается на web-странице.
Проанализируем функцию getCode(). Она реализована в файле script/script.js (листинг 5.2-2).
Листинг 5.2-2 – Содержимое функции getCode()
1. |
function getCode(username, password) { |
2. |
if (username.length !== password.length && username.length > 0 && password.length > 0) { |
3. |
alert('Длина имени пользователя и пароля не совпадают!'); |
4. |
return String(''); |
5. |
} |
6. |
const str = getBaseString(); |
7. |
const nums = '0123456789'; |
8. |
let res = Bar(); |
9. |
let check = Foo(); |
10. |
let code = ''; |
11. |
let pos1 = -1; |
12. |
let pos2 = -1; |
13. |
let letter = ''; |
14. |
for (let i = 0; i < username.length; i++) { |
15. |
pos1 = str.indexOf(username[i]); |
16. |
pos2 = nums.indexOf(password[i]); |
17. |
if (pos1 === -1 || pos2 === -1) { |
18. |
code += '-'; |
19. |
} |
20. |
else { |
21. |
letter = str[(pos1 + pos2) % str.length]; |
22. |
if (letter === Foo(i)) |
23. |
code += letter.toUpperCase(); |
24. |
else |
25. |
code += letter; |
26. |
} |
27. |
} |
28. |
if (code.toLowerCase() === check.toLowerCase()) { |
29. |
return res; |
30. |
} |
31. |
else { |
32. |
return code; |
33. |
} |
34. |
} |
В самой функции интерес представляет лишь последняя конструкция if (строки 28-33). В этих строках и формируется результат. Если условие в строке 28 верное, то результатом выполнения функции является переменная res, иначе переменная code. Значение переменной res получается из функции Bar() (строка 8).
Проанализируем функцию Bar(), которая реализована в файле script/proof.js (листинг 5.2-3).
Листинг 5.2-3 – Содержимое функции Bar()
1. |
function Bar() { |
2. |
const arr = [67, 110, 98, 98, 54, 27, 76, 104, 91, 98, 91, 105]; |
3. |
let res = ''; |
4. |
for (let i = 0; i < arr.length; i++) { |
5. |
res = res + String.fromCharCode(arr[i] + i); |
6. |
} |
7. |
return res; |
8. |
}; |
Функция преобразовывает массив чисел в символы в соответствии с ASCII-таблицей. Можно запустить в отладчике эту функцию и посмотреть результат ее выполнения (ответом будет строка “CODE: ROCKET”), а можно в функции getCode() в строке 32 вместо строки
return code;
записать
return Bar(); ИЛИ return res;
Тогда при любых значениях логина и пароля с одинаковой длиной получится следующий результат (рисунок 5.2-3).
Рисунок 5.2-3 – Содержимое web-страницы с измененной функцией getCode()