✍️ Статья Атаки на JavaScript. Часть 2

The 146X Project Dublikat Web Studio Avram Lincoln AL Service Navigator Knyaz

Tartuga

💰 Проверенный продавец
Регистрация
19.12.2019
Сообщения
93
В DVWA поднимите уровень безопасности до medium.

Между прочим, даже до вникания в особенности работы страницы, обратите внимание, что «детский» метод с сохранением страницы и изменением формы по-прежнему работает!

Но приступим к отладке, поскольку далеко не все случаи такие простые: например, форма отправки может вообще отсутствовать в исходном коде и создаваться на лету средствами JavaScript.

Посмотрим в исходный код страницы, JavaScript был вынесен в отдельный файл:

<script src="../../vulnerabilities/javascript/source/medium.js"></script>

Содержимое этого файла такое:

function do_something(e){for(var t="",n=e.length-1;n>=0;n--)t+=e[n];return t}setTimeout(function(){do_elsesomething("XX")},300);function do_elsesomething(e){document.getElementById("token").value=do_something(e+document.getElementById("phrase").value+"XX")}

Чтобы сделать код JavaScript читаемым я воспользуюсь инструментом JStillery.

Скачиваем интересующий файл:


Запускаем деобфускацию:

./jstillery_cli.js medium.js

Получено:

function do_something(e)
/*Scope Closed:true*/
{
for (var t = '', n = e.length - 1; n >= 0; n--)
t += e[n];
return t;
}
setTimeout(function ()
/* Called:undefined | Scope Closed:false| writes:false*/
{
do_elsesomething('XX');
}, 300);
function do_elsesomething(e)
/*Scope Closed:false | writes:true*/
{
document.getElementById('token').value = do_something(e + document.getElementById('phrase').value + 'XX');
}

pRaPvoVrFxQ.jpg

Если присмотреться к исходной строке, то можно увидеть, что код не обфусцирован, а сжат. В любом случае, теперь стало намного понятнее.

Из трёх функций фактически используется только последняя, а остальные, видимо, добавлены чтобы нас запутать.

Начинаем отладку кода, чтобы заменить значение переменной для получения нужного нам токена.

В веб-браузере вновь переходим в Инструменты разработчика (F12), находим файл medium.js. Чтобы привести сжатый JavaScript в понятный вид нажмите кнопку { }:

V1bv0mfIri4.jpg

Анализ кода подсказывает, что стоит обратить внимание на функцию:

function do_elsesomething(e) {
document.getElementById("token").value = do_something(e + document.getElementById("phrase").value + "XX")
}

Ставим точку прерывания там. Поскольку в одной строке выполняется сразу несколько операций, выбираем последнюю позицию для точки прерывания:

SGmg-S6QD-Y.jpg

Перезагружаем страницу.

cR22_OdpRWU.jpg

Видим, что переменной e присвоено значение «XX». Нажимаем F9 для перехода к следующему шагу.

Как видно, я был неправ говоря, что первые две функции добавлены только чтобы нас запутать — готовится вызов первой функции и в качестве параметра ей будет передано «XXChangeMeXX». Видимо, это и есть начало вычисления токена.

05XR5IbWMmc.jpg

Я присвоил параметру e значение «success», но получил ошибку о неверном токене. По аналогии с передаваемым значением («XXChangeMeXX»), назначем e строку «XXsuccessXX».

ssyttuBpLKY.jpg

Затем нажимаем F8 для продолжения выполнения кода JavaScript без отладки и прерываний.

Вводим на странице слово «success»:

mkf5GHOqWS0.jpg

И отправляем:

0WhbqN7o8cY.jpg

Как можно увидеть, всё прошло сработало.

4. Отладка обфусцированного кода JavaScript
В DVWA поднимите уровень безопасности до High.

JavaScript код вновь вынесен в файл high.js, посмотрим на него:

C9YXr2nBwvc.jpg

Код обфусцирован, я попробовал применить JStillery, но принципиально ничего не изменилось — код остался полностью нечитаем.

Самый лучший результат показал JavaScript онлайн деобфускатор deobfuscatejavascript.com, адрес этого сервиса: http://deobfuscatejavascript.com/

После деобфускации получился большой фрагмент JavaScript кода.

rXUExfSNoo4.jpg

В конце кода есть следующие функции:

function do_something(e) {
for (var t = "", n = e.length - 1; n >= 0; n--) t += e[n];
return t
}
function token_part_3(t, y = "ZZ") {
document.getElementById("token").value = sha256(document.getElementById("token").value + y)
}
function token_part_2(e = "YY") {
document.getElementById("token").value = sha256(e + document.getElementById("token").value)
}
function token_part_1(a, b) {
document.getElementById("token").value = do_something(document.getElementById("phrase").value)
}
document.getElementById("phrase").value = "";
setTimeout(function() {
token_part_2("XX")
}, 300);
document.getElementById("send").addEventListener("click", token_part_3);
token_part_1("ABCD", 44);

Обратите внимание на строку:

document.getElementById("token").value = do_something(document.getElementById("phrase").value)

В ней считывается значение поле phrase. У меня подозрение, что огромный код до этих функций не выполняет ничего нужного и размещён просто чтобы запутать нас. Но в любом случае, хотим ли мы делать отладку всего кода либо только указанного фрагмента, главный вопрос — как именно в файл вставить наш деобфусцированный код? Если не ответить на этот вопрос, то отладка обфусцированного кода может стать невозможной, так как предыдущий бессмысленный код может выполнять миллионы операций прежде чем управление перейдёт к действительно функциональному фрагменту.

Выход из этой ситуации есть — причём функция изменения файлов на лету и сохранение этих изменений даже после перезагрузки страницы есть прямо в Инструментах разработчика браузера.

Вставляем деобфусцированный код, ставим точку прерывания:

mmDQMnIpSEw.jpg

Добавляем эту страницу в «Save for overrides» как это описано в статье по ссылке выше и перезагружаем страницу.

Пожалуй, не буду разбирать этот пример до конца — будет это будет домашним заданием.

Заключение
На практике встречаются очень сложные для анализа варианты использования JavaScript, комбинирующие динамическое построение DOM структуры страницы, динамическое назначение событий, обфускацию кода, использование громоздких фреймворков и т. д. Но в целом исходить нужно из того, что защиты на стороне пользователя, в том числе с использованием JavaScript априори являются ненадёжными.

JavaScript может использоваться, например, для верификации данных в форме, но только для удобства пользователя, чтобы сообщить ему, что пропущено какое-то обязательное поле или введена информация в неверном формате. Но на стороне сервера всё обязательно должно перепроверяться так, как будто бы на стороне пользователя не было никаких проверок. Нужно исходить из того, что с пользовательской стороны может прийти что угодно.
 

📌 Золотая реклама

AnonPaste

Верх