Нужна помощь с перебором кода для crypt(3)

Я пытаюсь разработать программу на C, которая «взломает» шифрование crypt(3), используемое в UNIX. Я думаю, самый наивный способ сделать это - перебор. Я подумал, что должен создать массив, содержащий все символы, которые может иметь пароль, а затем получить все возможные их перестановки и сохранить их в двумерном массиве (где все 1-символьные пароли сохраняются в первой строке и т. д.) для петли. Есть ли лучший способ сделать это? С петлями довольно грязно.


person Community    schedule 17.11.2009    source источник
comment
Вы не хотите хранить все перестановки — просто проверяйте и отбрасывайте по мере их создания.   -  person Greg    schedule 17.11.2009
comment
У вас действительно достаточно памяти для хранения всех возможных перестановок?   -  person dsm    schedule 17.11.2009
comment
Нет, мой плохой. Я хотел сохранить каждую перестановку, которую я получаю временно, в массиве символов, которые я передам в крипту. То есть: 1) Переставить 2) Сохранить в строке (массиве) 3) Пропустить. При следующей перестановке предыдущая строка будет заменена. Я просто решил, что буду использовать двумерный массив, потому что не все пароли имеют одинаковую длину (и у меня не может быть пустых слотов массива).   -  person    schedule 17.11.2009


Ответы (2)


Предполагая, что можно использовать только 62 различных символа, для хранения всех возможных 8-символьных паролей требуется 62 ^ 8 = 198 терабайт.

Чтобы ответить на ваш вопрос loop, вот некоторый код для циклического перебора всех возможных паролей данного len, используя символы для данного набора:

int len = 3;
char letters[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
int nbletters = sizeof(letters)-1;

int main() {
    int i, entry[len];
    for(i=0 ; i<len ; i++) entry[i] = 0;
    do {
        for(i=0 ; i<len ; i++) putchar(letters[entry[i]]);
        putchar('\n');
        for(i=0 ; i<len && ++entry[i] == nbletters; i++) entry[i] = 0;
    } while(i<len);
}

Основная часть — это последний цикл for. В большинстве случаев он увеличивает только первую запись и останавливается на этом, так как эта запись не достигла nбукв. Если запись достигает nbletter, это означает, что она должна вернуться к нулю, и наступает очередь следующей записи, которая будет увеличиваться. Это действительно необычное состояние цикла: цикл продолжается до тех пор, пока не будет переполнения. Зацикливание происходит только в худшем случае: когда несколько записей находятся на последнем элементе.

Представьте себе случай, когда текущее слово «zzzzc». В свою очередь, каждая запись увеличивается, обнаруживается ее переполнение, она сбрасывается в 0, и считается, что следующая запись, до последней записи, которая не переполняется, дает «000d».

person Jerome    schedule 17.11.2009
comment
Здравствуйте, спасибо за ответ! Не могли бы вы объяснить ту часть, где вы пишете: ++entry[i] == nbletters; Я не могу понять это условие, поэтому у меня проблемы с пониманием всей этой строки, которая, я думаю, самая важная! Спасибо - person ; 17.11.2009

Как отмечают комментаторы вопроса - у вас нет необходимой оперативной памяти, и вам не нужно все это хранить.

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

Подход к достижению полного охвата заключается в повторении 0 через количество перестановок и кодировании значения с размером вашего набора символов в качестве основы. Это может быть легко масштабировано до размера вашего набора символов.

(псевдокод, но вы поняли)


passChars = '[all characters used in this attempt]'

permutationCount = 8^len(passChars) #crypt(3) only uses 8 chars

output = ''

for looper = 0 to permutationCount - 1
    localTemp = looper
    while localTemp > 0
        output += passchars[localTemp%len(passchars)] # % being modulus
        localTemp = floor(localTemp/len(passChars))


person Bell    schedule 17.11.2009