реализация атак грубой силы на хэш-значения в Javascript

Прежде чем я перейду к самому вопросу, я хотел бы прояснить некоторые вещи, потому что я знаю, как нелепо может звучать «грубая форсировка с помощью javascript», когда она вырвана из контекста :).

Я работаю над своей бакалаврской диссертацией, в конце которой я стремлюсь реализовать экспериментальный взломщик хэшей на основе Javascript. Идея состоит в том, чтобы работать следующим образом: пользователи могут отправлять хэш-значение вместе с информацией об используемом алгоритме. (Другие) пользователи также могут нажать кнопку на веб-сайте, чтобы принять участие в процессе взлома. Задача сервера — принимать и разбивать поданные «заказы» на диапазоны в зависимости от количества доступных работников. Затем диапазоны отправляются клиентам, которые нажали указанную кнопку.

В настоящее время я застрял с двумя большими вопросами о том, как на самом деле реализовать эту функцию грубой силы. Итак, моя главная проблема сейчас в том, что, честно говоря, я еще не совсем освоился с Javascript. Для начала я бы просто использовал жестко закодированный набор символов: буквенно-цифровой, нижний и верхний регистр, никаких специальных символов. Проблема в том, что я, честно говоря, понятия не имею, как на самом деле реализовать функцию, которая будет проверять все комбинации символов, как это запрограммировать. Я могу представить себе использование обычного массива, содержащего кодировку, а затем две строки. Одна строка будет содержать диапазон, другая — проверенные комбинации. Так что мне каким-то образом пришлось бы перебирать массив кодировок и строки, возможно, с каскадными циклами for или чем-то еще, но я действительно застрял с вопросом «как именно» :). Я не ожидаю, что кто-либо из вас действительно предоставит мне полный исходный код такой функции (если вы этого, конечно, не захотите), но я был бы очень признателен за некоторые подсказки или объяснения о том, как реализовать такую ​​функцию грубой силы. На данный момент я бы также не беспокоился о производительности или оптимизированном кодировании, а скорее о комплексном кодировании или как бы вы это ни называли :)

Извините, если я запутался в некоторых деталях в своем вопросе. Если да, скажите, и я, конечно, постараюсь уточнить дальше.


person slagjoeyoco    schedule 05.09.2012    source источник
comment
Вы можете получить лучший ответ на security.stackexchange.com   -  person Mike Samuel    schedule 05.09.2012
comment
хм, возможно, это правда, спасибо - мне еще предстоит внимательно изучить, какие форумы есть на этой платформе обмена стеками здесь :). Я опубликую там, но я надеюсь, что все в порядке, если я оставлю этот вопрос здесь открытым, посмотрим, что произойдет.   -  person slagjoeyoco    schedule 05.09.2012
comment
Второй вопрос должен быть на отдельной странице - просто удалите его отсюда. Если вы хотите узнать, какие возможности вы должны использовать, спросите на форуме безопасности. Если вы знаете, какие слова должны быть сгенерированы, но не знаете, как, скажите нам, что это за слова.   -  person Bergi    schedule 05.09.2012
comment
Хорошо, хорошо, я убрал часть о второй проблеме. Что вы имеете в виду, с какими словами следует генерировать? В целом я знаю, как работает грубая сила: в основном, чтобы попробовать все возможные комбинации символов, взятых из заданного набора символов. Моя проблема в том, что я не знаю, как реализовать это с точки зрения программирования, с точки зрения «какие процессы/действия я могу использовать для выполнения этой задачи».   -  person slagjoeyoco    schedule 06.09.2012


Ответы (1)


Функция стиля грубой силы над алфавитом. Вероятно, есть более простые способы сделать это.

function brute(alphabet, match, int_start, int_stop){
    var a = alphabet, al = 0,                     // for alphabet
        m = match.toString(), ml = m.length,      // for our compare
        i = int_start || 0, j = int_stop || 0,    // range of numbers to test
        k = 0, l = 0, add = 0, sub = 0, diff = 0, // for building test string
        test = '', found = false;                 // test string and result

    if(i < 0) throw 'int_start must be at least 0';

    if(a.constructor !== undefined){           // We need a string or array as
        if( a.constructor.name !== 'String' && // our alphabet so we check for
            a.constructor.name !== 'Array' )   // correct input and modify if
                a = a.toString();              // necessary, or if we can't, 
    }
    else throw 'Bad alphabet type';            // we throw an error

    al = a.length;    // shorthand length

    add = al;                             // when i=0, we start prefix here
    while(add <= i - sub) sub += add,     // then work out what we have to
                          add = add * al; // prefix our number with

    diff = add - sub; // shorthand to save calculations

    while( i < j ){   // actual brute force loop starts here
        test = '';       // empty any previous string
        k = diff + i;    // convert our number from "x" to "1x"

        while(k > 0){           // build it as a string
            l = k % al;         // get index of digit
            test = a[l] + test; // add digit to string
            k = ( k - l ) / al; // move digits along
        }

        test = test.substring(1); // cut off the initial "1" we added

        if(test.length === ml && test === m){ // compare test to what you want
            found = true;
            break;
        }

        i++;                  // prepare for our next loop
        if(i - sub === add)   // and if we need another digit
            sub += add,       // then recalculate our prefix
            add = add * al,   // and then
            diff = add - sub; // update the shorthand 
    }

    // brute force ended, let's see what we've got

    if(found === false) i = -1; // if not found, return -1 as index

    return [i, test, m]; // index found, string found with, what we were looking for
}

Затем используйте через, например.

brute('0123abcd', '0c', 0, 20); // [14, "0c", "0c"]
person Paul S.    schedule 05.09.2012
comment
Спасибо за вашу помощь, но именно по этой причине я сказал, что письменные объяснения или просто подсказки были бы хороши - вы потеряли меня сразу после того, как было выбрано исключение - оттуда я .... Я действительно не понимаю, что здесь происходит: ). Если бы вы хотели немного уточнить, это было бы очень здорово. Но в любом случае спасибо за попытку помочь. - person slagjoeyoco; 06.09.2012
comment
После первого исключения - проверьте type ввода для alphabet, если это не строка, преобразуйте ее в строку (потому что вы можете делать вещи в стиле массива для строк). После второго исключения идет сложный бит — если вы хотите посчитать (например, в двоичном формате, основание 2) 0, 1, 10, 11, 100, 101, 110, 111, это ЛЕГКО, но если вы хотите сделать 0, 1, 00, 01, 10, 11, 000, 001, ..., это намного сложнее. Один из способов сделать это — работать с базой выше (например, с базой 3), что я и сделал. Затем переберите целое число => символы. - person Paul S.; 06.09.2012
comment
Чтобы проверить хэши, вы должны изменить строку if(test.length === ml && test === m), чтобы проверить хэш test на соответствие тому, что вы хотите найти (например, if(myHash(test) === match)). - person Paul S.; 06.09.2012
comment
Это беспокоило меня, но потом я заметил, что метод, который я сделал сначала, был неправильным (повторялся в середине), поэтому я изменил его МНОГО и добавил комментарии почти к каждой строке. Новый метод ставит перед идентификатором префикс (1), а затем обрезает его, поэтому мы получаем все результаты. @slagjoeyoco надеюсь, что это более полезно. - person Paul S.; 06.09.2012
comment
Привет и большое спасибо за добавление комментариев, очень полезно. Либо у меня сейчас не хватает кофе, либо я просто глуп с точки зрения простой математики, но после некоторого размышления и дурачиться с вашим кодом у меня осталось два вопроса: 1) теперь я вижу, что вы делаете в последний if-check, чтобы узнать, нужна ли вам еще одна цифра или нет, но: как, черт возьми, вы придумали этот источник?! :) Есть ли более простой способ узнать это? Я имею в виду, как вы узнали, что эти числа всегда будут сыграны? Извините за запутанный вопрос, но я действительно не знаю, как еще спросить... - person slagjoeyoco; 07.09.2012
comment
и 2) я думаю, что я все еще что-то упускаю, но для чего именно нам нужен префикс? Поскольку количество записываемых цифр зависит от количества циклов в цикле while(k > 0), что опять же зависит от diff. Итак, какова цель префикса? Кроме того, я понимаю, почему вы извлекаете из тестовой строки все, кроме префикса, но ГДЕ именно он добавляется? Из того, что я вижу, префикс вычисляется, но на самом деле никогда не добавляется в строку, или это так? - person slagjoeyoco; 07.09.2012
comment
Здесь добавляется префикс: k = diff + i;, а не k = i;. Его цель состоит в том, чтобы предотвратить отображение комбинаций с предыдущими нулевыми цифрами (например, 0001) как просто 1. Мы знаем, как вычислить префикс, потому что знаем размер алфавита — префикс всегда должен быть на одну цифру длиннее, чем число, с которым мы работаем, и каждый раз, когда мы это делаем, нам нужно снова начинать счет с нуля, но, к счастью, мы знаем, как давно это было, потому что это было наше предыдущее значение add. То, что мы не вносим эти изменения в i, позволяет разделить отправленные «заказы» на диапазоны. - person Paul S.; 07.09.2012
comment
Чтобы объяснить, почему мы знаем, как давно это было, потому что это было наше предыдущее значение add, подумайте о длине текущего числа (в нашем алфавите) как о j, тогда вместо того, чтобы просто выбирать любое число длины j+1, нам нужно выбрать одно который представляет собой одну цифру, за которой следуют j (алфавита) нули, самый простой - это 1 алфавита. Затем этот номер достигается текущим номером именно тогда, когда текущему номеру нужна новая цифра. - person Paul S.; 07.09.2012
comment
Хорошо, называйте меня тупым, но когда я подумал, что понял это сейчас, я понял, что понял только половину :) ... Я вижу цель добавления префикса, чтобы сохранить некоторые определенные комбинации. Чего я не понимаю, так это того, что вы говорите, что мы делаем k = diff + i; чтобы превратить x в 1x, чтобы добавить «1», верно? Теперь я немного поиграл с ti, и, может быть, это просто совпадение, но k почти всегда оказывалось чем угодно, кроме 1x. Кроме того, если префикс добавляется к k, зачем тогда мы пытаемся извлечь его из «теста»? На самом деле это никогда не добавлялось туда, не так ли? - person slagjoeyoco; 08.09.2012
comment
И во всех тестовых прогонах, которые я выполнял с этой функцией, я никогда не замечал разницы между ее запуском без добавления префикса и запуском с добавлением префикса - результирующая тестовая строка всегда совпадала... не знаю, что мне здесь не хватает, но определенно что-то есть. Большое спасибо за то, что так терпеливо приветствовали меня до сих пор, правда ценю это :) - person slagjoeyoco; 08.09.2012
comment
Установите свой алфавит на что-нибудь базовое, например, 012 или ABC, и попробуйте найти 000 или AAA с префиксом и без него. - person Paul S.; 08.09.2012
comment
Хм, да, это объясняет: D - без установки префикса нам нужно больше попыток, потому что в некоторых случаях тестовая строка пуста ... Я имею в виду, что я понимаю цель префикса (сейчас больше, чем когда-либо), а также общий процесс настройка теперь понятна, наверное у меня просто проблемы с пониманием как узнать как точно рассчитать, ну да ладно... - person slagjoeyoco; 08.09.2012
comment
Скажем, j — это длина числа x, используя ваш алфавит, тогда для вычисления prefix вы можете сделать Math.pow( alphabetLength, j ). Это alphabetLength * alphabetLength * .. * alphabetLength, j раз, что вы можете сделать в цикле. Почему я использую цикл в коде? Поскольку каждый раз, когда мы удлиняем цифру, мы хотим снова начать с 0, что означает, что, хотя int_start отображается на x, на самом деле это не x, потому что он также содержит информацию о том, сколько цифр мы добираемся до ( x = i - sub, k = prefix + x, в коде я называю префикс add ) - person Paul S.; 08.09.2012
comment
Привет - очень извините за мой запоздалый ответ. Теперь я понимаю, что вы имеете в виду из вашего последнего объяснения. Конечно, int_start хранит текущую начальную позицию, что позволяет функции работать с любым диапазоном. Большое спасибо за вашу помощь и терпение, я очень ценю это :) - person slagjoeyoco; 12.09.2012