Изучение скриптов External Mode в John the Ripper

Kali LinuxBeginner
Практиковаться сейчас

Введение

John the Ripper (JtR) — это популярный и мощный инструмент с открытым исходным кодом для аудита безопасности паролей и восстановления паролей. Он может выполнять взлом паролей с использованием нескольких режимов, таких как режим "single crack", режим "wordlist" и режим "incremental".

Помимо этих стандартных режимов, JtR предлагает невероятно гибкий "External Mode" (Внешний режим). Этот режим позволяет использовать внешнюю программу или скрипт для генерации кандидатов в пароли. Это дает вам полный контроль над логикой генерации паролей, позволяя создавать высоконастроенные и сложные шаблоны паролей, которые невозможны в других режимах.

В этой лабораторной работе вы изучите основы External Mode в JtR. Вы начнете с понимания основных концепций, затем напишете, скомпилируете и используете собственную пользовательскую программу на C для генерации паролей. Вы также изучите основные методы отладки и примените свои знания в более практическом сценарии.

Понимание основ External Mode

На этом шаге вы изучите основные концепции External Mode в John the Ripper. Этот режим работает путем выполнения внешней программы, которую вы определяете. Затем John the Ripper считывает стандартный вывод этой программы, рассматривая каждую строку как потенциального кандидата в пароли.

Эти внешние режимы определяются в конфигурационном файле john.conf, который обычно находится по адресу /etc/john/john.conf. Каждый внешний режим определяется в разделе вида [List.External:ModeName].

Давайте рассмотрим существующее определение внешнего режима в файле конфигурации по умолчанию, чтобы увидеть его структуру. Мы найдем режим Keyboard, который имитирует кандидатов в пароли на основе шаблонов последовательного нажатия клавиш на клавиатуре.

Выполните следующую команду, чтобы просмотреть конфигурацию режима Keyboard:

grep -A 10 "\[List.External:Keyboard\]" /etc/john/john.conf

Вы увидите блок кода, похожий на C. Самая важная функция — generate(), которая отвечает за создание кандидатов в пароли.

Чтобы увидеть внешний режим в действии, вы можете запустить john с флагом --stdout. Это указывает John выводить сгенерированных кандидатов на экран вместо попытки взлома хэша. Давайте протестируем режим Keyboard.

john --stdout --external=Keyboard | head -n 5

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

q
w
e
r
t

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

Написание простого скрипта для External Mode

На этом шаге вы напишете и скомпилируете свой первый простой скрипт для External Mode, используя язык программирования C. Наша цель — создать программу, которая генерирует фиксированный список паролей, а затем настроить John the Ripper для ее использования.

Сначала создадим файл исходного кода на C с именем simple_gen.c с помощью редактора nano.

nano simple_gen.c

Теперь скопируйте и вставьте следующий код на C в редактор nano. Эта программа просто выведет три разных пароля в стандартный вывод, каждый на новой строке.

#include <stdio.h>

int main() {
    printf("pass1\n");
    printf("pass2\n");
    printf("pass3\n");
    return 0;
}

Нажмите Ctrl+X, затем Y и Enter, чтобы сохранить файл и выйти из nano.

Далее скомпилируем этот код на C в исполняемый файл с именем simple_gen, используя компилятор gcc.

gcc -o simple_gen simple_gen.c

Теперь, когда у нас есть исполняемый файл, нам нужно сообщить John the Ripper, как его использовать. Мы сделаем это, создав локальную копию конфигурационного файла в нашем каталоге проекта и добавив новое определение внешнего режима.

cp /etc/john/john.conf ./my_john.conf

Откройте новый файл my_john.conf с помощью nano.

nano my_john.conf

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

[List.External:MySimple]
void generate()
{
  exec("./simple_gen");
}

Сохраните и выйдите из nano (Ctrl+X, Y, Enter).

Наконец, протестируем наш новый внешний режим. Мы снова используем флаг --stdout, чтобы увидеть вывод, и флаг --config, чтобы указать John на наш пользовательский конфигурационный файл.

john --stdout --external=MySimple --config=./my_john.conf

Вы должны увидеть точный вывод нашей программы на C, подтверждающий, что John the Ripper успешно запускает наш пользовательский скрипт.

pass1
pass2
pass3

Реализация пользовательской логики генерации паролей

На этом шаге вы улучшите свой скрипт для реализации более динамичной логики генерации паролей. Вместо фиксированного списка мы будем генерировать пароли на основе шаблона: базовое слово, за которым следует последовательность чисел. Это распространенный шаблон для слабых паролей.

Давайте изменим нашу программу на C для генерации паролей вида labex0, labex1, labex2 и так далее.

Снова откройте файл simple_gen.c с помощью nano.

nano simple_gen.c

Замените существующий код следующим. Эта новая версия использует цикл for для добавления чисел от 0 до 199 к базовому слову "labex".

#include <stdio.h>

int main() {
    char *base_word = "labex";
    for (int i = 0; i < 200; i++) {
        printf("%s%d\n", base_word, i);
    }
    return 0;
}

Сохраните и выйдите из nano. Теперь перекомпилируйте программу с помощью gcc, чтобы применить изменения.

gcc -o simple_gen simple_gen.c

Давайте протестируем обновленный генератор с флагом --stdout, чтобы увидеть пример нового вывода.

john --stdout --external=MySimple --config=./my_john.conf | head -n 5

Теперь вывод должен показать новый шаблон.

labex0
labex1
labex2
labex3
labex4

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

Выполните следующую команду, чтобы начать процесс взлома. Обратите внимание, что мы убрали --stdout и добавили путь к нашему файлу хэшей hashes.txt.

john --external=MySimple --config=./my_john.conf ./hashes.txt

John запустит ваш скрипт, сгенерирует кандидатов и протестирует их против хэша. Он должен быстро найти пароль. Вывод будет выглядеть примерно так:

Using default input encoding: UTF-8
Loaded 1 password hash (sha512crypt, $6$ [SHA512 256/256 AVX2 4x])
Cost 1 (iteration count) is 5000 for all loaded hashes
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
labex123         (testuser)
1g 0:00:00:00 DONE (2024-05-20 08:30) 100.0g/s 12300p/s 12300c/s 12300C/s labex123..labex130
Use the "--show" option to display all of the cracked passwords reliably
Session completed

Чтобы подтвердить взломанный пароль, используйте опцию --show.

john --show ./hashes.txt

Это отобразит взломанный пароль рядом с именем пользователя.

testuser:labex123:1001:1001::/home/testuser:/bin/sh

1 password hash cracked, 0 left

Отладка скриптов External Mode

На этом шаге вы изучите основные методы отладки ваших скриптов для External Mode. Когда скрипт работает не так, как ожидалось, диагностировать проблему может быть сложно, поскольку он запускается другой программой (John the Ripper).

Распространенным и эффективным методом отладки является запись сообщений журнала из вашего скрипта в отдельный файл. Это позволяет отслеживать поток выполнения и проверять значения переменных.

Давайте модифицируем нашу программу на C для записи в файл журнала с именем debug.log. Откройте simple_gen.c с помощью nano.

nano simple_gen.c

Замените код следующей версией. Этот код открывает debug.log для записи, а затем использует fprintf для записи сообщений о состоянии в него во время выполнения.

#include <stdio.h>
#include <stdlib.h>

int main() {
    FILE *log_file = fopen("debug.log", "w");
    if (log_file == NULL) {
        // Не удалось открыть файл журнала, выход
        return 1;
    }

    fprintf(log_file, "Debug: Script started.\n");

    char *base_word = "labex";
    for (int i = 0; i < 200; i++) {
        printf("%s%d\n", base_word, i);
        fprintf(log_file, "Debug: Generated candidate %s%d\n", base_word, i);
    }

    fprintf(log_file, "Debug: Script finished.\n");
    fclose(log_file);
    return 0;
}

Сохраните и выйдите из nano, затем перекомпилируйте программу.

gcc -o simple_gen simple_gen.c

Теперь снова запустите John the Ripper. Нам не нужно видеть кандидатов паролей, поэтому мы можем перенаправить стандартный вывод в /dev/null. Важно то, что наш скрипт будет запущен и создаст файл журнала.

john --stdout --external=MySimple --config=./my_john.conf > /dev/null

Команда выполнится некоторое время и завершится. Теперь в вашем каталоге проекта должен существовать файл debug.log. Давайте посмотрим его содержимое.

cat debug.log | head -n 5

Вы должны увидеть отладочные сообщения, которые мы добавили в нашу программу.

Debug: Script started.
Debug: Generated candidate labex0
Debug: Generated candidate labex1
Debug: Generated candidate labex2
Debug: Generated candidate labex3

Этот метод бесценен для поиска проблем в вашей логике, таких как неправильные циклы, неверные значения переменных или ошибки доступа к файлам, без помех от собственного вывода John the Ripper.

Применение External Mode к конкретным сценариям

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

Сначала давайте создадим простой файл списка слов с именем words.txt, содержащий несколько потенциальных базовых слов.

echo "admin" > words.txt
echo "user" >> words.txt
echo "guest" >> words.txt

Далее мы модифицируем нашу программу на C для чтения этого файла. Программе потребуется принимать имя файла списка слов в качестве аргумента командной строки. Откройте simple_gen.c с помощью nano.

nano simple_gen.c

Замените код следующим. Эта версия считывает имя файла из командной строки, открывает этот файл и для каждого прочитанного слова генерирует три кандидата в пароли: само слово, слово с добавлением "123" и слово с добавлением "2024".

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]) {
    if (argc < 2) {
        fprintf(stderr, "Usage: %s <wordlist_file>\n", argv[0]);
        return 1;
    }

    FILE *file = fopen(argv[1], "r");
    if (file == NULL) {
        perror("Error opening file");
        return 1;
    }

    char line[256];
    while (fgets(line, sizeof(line), file)) {
        // Удалить символ новой строки в конце строки
        line[strcspn(line, "\n")] = 0;

        // Генерация вариаций для слова
        printf("%s\n", line);
        printf("%s123\n", line);
        printf("%s2024\n", line);
    }

    fclose(file);
    return 0;
}

Сохраните, выйдите и перекомпилируйте программу.

gcc -o simple_gen simple_gen.c

Теперь мы должны обновить наш файл my_john.conf, чтобы передать имя файла words.txt в качестве аргумента нашему скрипту. Давайте создадим для этого новый внешний режим под названием MyAdvanced. Откройте my_john.conf с помощью nano.

nano my_john.conf

Прокрутите до конца файла и добавьте этот новый раздел. Обратите внимание, как "words.txt" передается в качестве второго параметра функции exec.

[List.External:MyAdvanced]
void generate()
{
  exec("./simple_gen", "words.txt");
}

Сохраните и выйдите из nano. Наконец, протестируйте ваш новый расширенный внешний режим.

john --stdout --external=MyAdvanced --config=./my_john.conf

Теперь вывод должен представлять собой список кандидатов в пароли, сгенерированных из слов в вашем файле words.txt, с примененными к каждому указанными вариациями.

admin
admin123
admin2024
user
user123
user2024
guest
guest123
guest2024

Вы успешно создали гибкий генератор паролей на основе файлов для John the Ripper.

Резюме

Поздравляем с завершением этой лабораторной работы! Вы успешно изучили мощный режим External Mode программы John the Ripper.

В этой лабораторной работе вы узнали:

  • Основную концепцию режима External Mode программы John the Ripper и как он использует внешние программы для генерации кандидатов в пароли.
  • Как написать, скомпилировать и использовать простую программу на C в качестве генератора паролей.
  • Как настроить пользовательский внешний режим в файле john.conf.
  • Как реализовать динамическую логику генерации паролей на основе шаблонов.
  • Как использовать ваш пользовательский режим для успешного взлома хэша пароля.
  • Базовый, но эффективный метод отладки ваших внешних скриптов путем ведения журнала в файл.
  • Как создать более продвинутый и практичный скрипт, который считывает базовые слова из файла.

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