Гипотеза о генераторах паролей...

Discussion in 'Криптография, расшифровка хешей' started by Грабитель, 6 Dec 2015.

  1. Грабитель

    Joined:
    5 Mar 2013
    Messages:
    196
    Likes Received:
    12
    Reputations:
    -7
    Как вы знаете, многие пользователи генерируют свои пароли разными генераторами, хеши которых считаются\считались небрутабельными.
    Грубо говоря сгенерированные скажем 15 символов с участием a-zA-Z0-9 получаем что то типа: 72oqNAGDqN2XDqZ, такой пароль даже в md5 хешировании сбрутить не возможно… но только если брутить напрямую влоб.

    Суть вот в чем, в подавляющем большинстве случаев, в основе генератора на разных языках программирования, будь то C++, php, javascript и прочие, в основе генерации пароля лежит функция rand(), которая является псевдослучайной.
    Вычислив эти «псевдослучайности», теоретически можно сгенерировать все возможные комбинации, или их часть, которая по сути не является случайным паролем, таким образом создать словарь со «сгенерироваными» паролями, разной длинны, и с разными символами a-z или a-z0-9 или a-zA-Z0-9 и так далее.

    Если где то уже ведутся или велись обсуждения подобных уязвимостей генерируемых паролей, поделитесь ссылкой. Как мне кажется, вполне возможно на основе псевдослучайности создать особые словари с хорошим пробивом по тем хешам, владельцы которых генерируют свои пароли разными генераторами.
     
  2. Logan22

    Logan22 Member

    Joined:
    11 Sep 2009
    Messages:
    119
    Likes Received:
    17
    Reputations:
    0
    Никогда не пользовался генераторами, по той причине что подавляющей своей массе количество пользователей делают свой пароль человекопонятным.
    И чем меньше пользователь шизофреник , тем больше его пароль будет из состоять из понятных слов или фраз.
    Генератор не создаст такой пароль "СамыйЛучшийПароль" и это понятно он не ИИ, а пользователь может, генератор сделает как-то так "J0wRRjS81Wr".
    И шанс что пользователь использует такие символы ничтожны.

    Что сделал Я с целью получить такой пароль!
    Всё очень просто, для создания таких словарей надо иметь огромный массив слов и которые будут по разному склонены.
    Книги, книги это то что нам поможет. Я сделал массив из сотни тыс. книг. Где взять эти самые книги?
    Скачиваем их к примеру с сайта tululu.org.
    Примерно как-то так.
    PHP:
    for ($i 1$i <= 10000$i++) {
        
    $ch curl_init('http://tululu.org/txt.php?id='.$i);
        
    $fp fopen('bookmy/d'.$i.'.txt''wb');
        
    curl_setopt($chCURLOPT_FILE$fp);
        
    curl_setopt($chCURLOPT_HEADER0);
        
    curl_exec($ch);
        
    curl_close($ch);
    }
    fclose($fp);
    echo 
    'Скачено '.$i.' книг';
    Когда скрипт загрузит текстовые книги, Вы получите огромную базу , и далее объединяем их в один текстовый массив данных и удаляем дубли.
    После этого мы можем делать генерировать из этого словаря любые пароли/фразы, все действия ограничены вашей фантазией и знаниями.
    Думаю разжевал понятно каждому.
     
  3. Anklav

    Anklav Active Member

    Joined:
    14 Aug 2016
    Messages:
    165
    Likes Received:
    113
    Reputations:
    4
    Восстанавливаю свой пост, с некоторыми дополнениями, который был утрачен в связи с падением сайта:

    Недостатки у программных генераторов паролей могут быть следующие:

    - генератор может создавать конечное число повторяющихся паролей, уступающее по количеству всему спектру возможных комбинаций, при заданной длине. А это значит что пароль в 10 знаков, созданный плохим генератором, может быть сопоставим с шестизначным истинно случайным, наприрмер. Если довести ситуацию до абсурда - генератор может выдавать всего 1000 паролей длиной 20 знаков, например. У юзера может сложиться впечатление неподбираемости пароля, но подобрать по словарю такой пароль займет микросекунды...

    - генератор может предлагать определенные пароли более часто (неравномерное распределение псевдослучайных величин). Т.е. плохие "кривые распределения". Он генерирует весь спектр возможных паролей - но некоторые значительно чаще других. Соответственно могут быть составлены словари наиболее вероятных паролей.

    - в генераторе паролей случайное число создаётся не аппаратным генератором истинно случайных велечин, а программно, собирая данные из системы, комбинируя их определенным образом и хешируя результат. Эти начальные данные называются seed. И зачастую все варианты seed можно перебрать. Дальнейшая генерация "случайного" пароля на базе seed детерминирована. Допустим если сид формируется на базе точного времени, версии ОС, данных о железе - не сложно составить словарь в котром будут перечислены все возможные комбинации (или значительная их часть), даже если это будут сотни миллиардов комбинаций - это можно приравнять к бруту 12ти значного цифрового пароля. Если сложный пароль длиной 20 знаков сгенерирован на базе такого сида - в нём нету никакого смысла. Ломается он просто. В хороших генераторах сиды формируются так, что подобрать их методом перебора практически невозможно.

    Чтобы разобраться с этим, на обывательском уровне (возможно математики знают способы лучше, сопряженные с анализом исходника генератора) необходимо каким-то образом создать словарь, достаточного размера (сопоставимого с теми, которыми пользуются ныне хэшкрякеры), генерированный проверяемой программой. Далее уже искать в нём повторения. Если окажется предлагаемые пароли распределяются не истинно случайным образом, но распределение генерируемых паролей сопоставимо с указанной длиной пароля - я думаю это терпимый недостаток, не дающий надежды для брута.

    Допустим генерируя пароли длиной 32 бита, генератор использует лишь четверть возможных комбинаций. Это можно сопоставить с полным спектром паролей длиной 30 бит. Если же мы ведем речь о паролях длиной 128 бит, то в этом случае истинное количество паролей будет - 2^(128-2). Что, собственно, не сильно облегчает задачу. Иное дело если генератор выдаст миллионную долю от возможных вариантов. Или повторит какой-то пароль с частотой 1:10^5. Это уже даёт небольшой, но шанс попасть вам в этот процент часто генерируемого пароля. Нужно смотреть какие кривые распределния даёт генератор паролей разной длины, начиная от 5 знаков, к примеру. Ну и оценить как формируется seed, сколько вариантов seed у генератора.

    Моё мнение - сил нормального генератора псевдослучайных чисел достаточно, чтобы лишить всякой надежды на брутфорс (при достаточной длине пароля) или подбор по словарям.

    На хабре есть хорошие статьи, посвященные распределениям, энтропии, уязвимостям генераторов:
    https://habrahabr.ru/post/151187/
    https://habrahabr.ru/post/274833/
    https://habrahabr.ru/post/128666/ etc.

    По keepass, в частности, информация такая:

    Random Number Generation

    KeePass needs to generate several random bytes (for the IV, the master key salt, etc.). For this, several pseudo-random sources are used: current tick count, performance counter, system date/time, mouse cursor position, memory status (free virtual memory, etc.), active window, clipboard owner, various process and thread IDs, various window handles (active window, desktop, ...), window message stack, process heap status, process startup information and several system information structures. Additionally, KeePass uses random bytes provided by the system's default CSP RNG.

    This pseudo-random data is collected in a random pool. To generate 16 random bytes, the pool is hashed (SHA-256) with a counter. The counter is increased after 16 generated bytes. This way, as many secure random bytes can be produced efficiently as needed.

    Без вариантов. Хэши из этих данных можно считать случайными. Нету метода обнаружить какую-либо зависимость. Отличные распределения.
     
    shanton and attache like this.
  4. summerstew

    summerstew New Member

    Joined:
    29 Dec 2016
    Messages:
    2
    Likes Received:
    0
    Reputations:
    0
    Если мне не изменяет память то количество всех паролей считается так: S = A^L (S - количество паролей, A - количество символов в алфавите, L - длина пароля). Т.е. даже при написании самого простого генератора паролей
    Code:
    {               string dic = "";
                    string tmp = "";
                    if (checkBox1.Checked)
                    {
                        char nchar;
                        for (int i = 65; i < 91; i++)
                        {
                            nchar = (char)i;
                            tmp += Convert.ToString(nchar);
                        }
                        dic += tmp;
                    }
                    if (checkBox3.Checked) dic += "0123456789";
                    if (checkBox4.Checked) dic += textSymbols.Text;
                    if (checkBox2.Checked)
                    {
                        tmp = "";
                        char nchar;
                        for (int i = 97; i < 123; i++)
                        {
                            nchar = (char)i;
                            tmp += Convert.ToString(nchar);
                        }
    
                    dic += tmp;
                    }
                TextPass.Text += label4.Text + "\r\n";
    
                for (int j = 1; j <= numericNumb.Value-1; j++)
                {
                    string pass = "";
                    Random mran = new Random(j);
             
                    for ( int i = 0; i < numericLen.Value; i++)
                    {
                        int index = Convert.ToUInt16(mran.NextDouble() * dic.Length) % dic.Length;
                        char ScharS = dic[index];
                        pass += Convert.ToString(ScharS);
                    }
                    TextPass.Text += pass + "\r\n";
    
                }
            }
        }
    
    По сути будет достаточно менять пароль с определенной частотой, что бы с помощью брута было трудно взломать. (там тоже есть формула какая то, надо - напишу, но это и так понятно).

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

    Недавно подсмотрел интересный и простой способ генерации паролей с использованием гаммирования по ГОСТУ.
    Скачали с гитхаба https://github.com/ViatcheslawS/Crypto и туда, просто генерировали key и s, вставляли то ли текст нужной длинны, то ли просто вводили фразу нужной длинны и получали зашифрованную, вот как раз зашифрованную использовали как пароль.
    Но это, конечно, бубен.

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

    Раз уж затронули статейке на хабе, то вот достаточно интересная статья по подбору пароля за 5 секунд https://habrahabr.ru/post/107243/
     
  5. RUS58

    RUS58 Member

    Joined:
    18 Nov 2016
    Messages:
    101
    Likes Received:
    7
    Reputations:
    0
    Подскажите как прикрутить к этому приложению свою почту? И когда пользователь введет свои данные что бы данные отсылались мне на почту!
    #include <iostream>
    #include <fstream>
    #include <string>
    using namespace std;

    void register_1();
    void read(string login, string parol);
    void login();
    struct users
    {
    string login;
    string parol;
    } users[100];

    int main()
    {

    cout << "1.Регистрация" << endl;
    cout << "2. Вход" << endl;
    int a;
    cin >> a;
    switch (a)
    {
    case 1:
    register_1();
    case 2:
    login();
    }
    }

    void register_1()
    {
    string login, parol;
    cout << "Введите логин:" << endl;
    cin >> login;
    cout << "Введите пароль:" << endl;
    cin >> parol;
    ofstream fout("users.txt", ios::app);
    fout << login << " " << parol << endl;
    cout << "Регистрация прошла успешно!" << endl;
    main();
    }

    void read(string login, string parol)
    {
    ifstream fin("/sdcard/users.txt");
    for (int i = 0; i < 100; i++)
    {
    fin >> users.login >> users.parol;
    }
    }

    void login()
    {
    string login, parol;
    cout << "Введите логин:" << endl;
    cin >> login;
    cout << "Введите пароль:" << endl;
    cin >> parol;
    read(login, parol);
    bool flag = true;
    for (int i = 0; i < 100; i++)
    {
    if (login == users.login && parol == users.parol)
    {
    cout << "Вы успешно вошли!" << endl;
    flag = false;
    break;
    }
    }
    if(flag == true);
    {
    cout << "Неверный логин или пароль!" << endl;
    }

    system("pause");
    main();
    }