Итерация по всем возможным комбинациям букв - PullRequest
0 голосов
/ 20 января 2019

Попытка взломать пароль с помощью грубой силы, но программа, похоже, не понимает, когда она нашла пароль.

Поэтому я попытался написать небольшую программу для взлома паролей с помощью грубой силы. в основном я перебираю все буквенные комбинации, используя вложенные циклы for (пароли не должны быть длиннее 4 букв), затем я использую crypt для пароля с заданной солью (при условии, что соль исправлена), чтобы проверить, взломал ли я пароль ( У меня есть доступ к зашифрованным паролям). Теперь у меня был вывод кода, который он генерирует, и похоже, что он перебирает все строчные варианты. Но почему-то никогда не найти пароль.

Теперь я сам создал зашифрованную версию, так что я знаю, что пароль длиной 4 буквы, это не проблема, и программа, кажется, перебирает все возможности, я думаю, так в чем может быть проблема? Является ли условие if неправильным?

Теперь я думаю, что это не самое элегантное решение проблемы, но я думаю, что общая идея верна. Но если есть проблема с этим вложенным циклическим подходом, я был бы рад узнать об этом :).

#define _XOPEN_SOURCE
 #include <unistd.h>

#include <stdio.h>
#include <string.h>
#include <cs50.h>
int main(int argc, string argv[]) {

if(argc < 2) {
printf("Please enter a password to crack! \n");
return 1;
}


char s[4] = "";



for(int i = 0; i <=27; i++) {

    if(i == 0)
    s[0] = 0;
    else
    s[0] =  i - 1 + 'a';

    if(strcmp(crypt(s, "50"), argv[1]) == 0) {

    break; }
        for(int j = 0; j <=26; j++) {
            if(j == 0)
            s[1] = 0;
            else
        s[1] = (j - 1 + 'a');

        if(strcmp(crypt(s, "50"), argv[1]) == 0)
        break;
            for(int k = 0; k <= 26; k++) {
                if(k == 0)
                s[2] = 0;

                s[2] =  (k - 1 + 'a');


            if(strcmp(crypt(s, "50"), argv[1]) == 0)
            break;
                for(int l = 0; l <= 26; l++) {
                    printf("%s \n", s);
                    if(l == 0)
                    s[3] = 0;
                    else
                    s[3] =  (l - 1 + 'a');



                    if(strcmp(crypt(s, "50"), argv[1]) == 0)
                    break;
                }

            }
        }


}

if (strcmp(crypt(s, "50"), argv[1]) != 0)
printf("Password not found");
else
printf("%s \n", s);

Ответы [ 2 ]

0 голосов
/ 20 января 2019

Строки C заканчиваются нулем, это означает, что строка в C в основном представляет собой массив байтов / символов (например, тот, который вы инициализируете: char s[4] = "";) с последним байтом, установленным в 0.

strcmp проходит через две строки (байтовые массивы) и сравнивает их одну за другой до тех пор, пока не найдет другой символ или пока не закончится обе строки, т. Е. Текущий сравниваемый байт равен 0 для обеих строк.Когда вы инициализируете свой массив символов s равным 4 байта и запишите в него 4 ненулевых байта, strcmp продолжит сравнение байтов после конца массива, поскольку он не достиг конца строки.Это также может привести к сбою вашей программы или к уязвимостям безопасности, потому что вы продолжаете читать в память, чего не должны делать.Чтобы обойти это, должным образом завершите ваши входные строки нулевым байтом и по возможности используйте функцию strncmp, которая принимает дополнительный параметр, указывающий, сколько символов должно сравниваться не более.

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

Если вы просто ищетебрутфорс некоторых паролей и на самом деле не хотите программировать его самостоятельно, вам, вероятно, будет лучше использовать какой-нибудь профессиональный инструмент, например https://hashcat.net/hashcat/.

0 голосов
/ 20 января 2019

Объявление char s[4] не может оставить место для нулевого символьного терминатора, когда массив содержит четыре ненулевых символа, в результате чего поведение не определено стандартом C.

...