• [ Регистрация ]Открытая и бесплатная
  • Tg admin@ALPHV_Admin (обязательно подтверждение в ЛС форума)

DeepPass - поиск паролей с помощью глубокого обучения

admin

#root
Администратор
Регистрация
20.01.2011
Сообщения
7,665
Розыгрыши
0
Реакции
135
Введение

Одной из рутинных задач, с которой операторы регулярно сталкиваются в большинстве случаев, является добыча данных (data mining). Хотя то, что именно ищут операторы, варьируется от среды к среде, есть одна общая цель, которая всегда интересует всех: пароли.

После Для просмотра ссылки Войди или Зарегистрируйся с Для просмотра ссылки Войди или Зарегистрируйся я начал обращать внимание на любые наступательные проблемы безопасности, которые могут быть дополнены с помощью ML. Для просмотра ссылки Войди или Зарегистрируйся я упомянул о различии между состязательным машинным обучением (adversarial machine learning) и наступательным машинным обучением (offensive machine learning). Уилл Пирс Для просмотра ссылки Войди или Зарегистрируйся состязательное машинное обучение как "субдисциплину, которая специально атакует алгоритмы машинного обучения", а наступательное машинное обучение как "применение машинного обучения для решения наступательных проблем безопасности", и я согласен с этими определениями. В моих предыдущих статьях я рассказывал о введении в состязательный ML, где мы создавали состязательные образцы, чтобы обойти существующие целевые модели. Наступательный ML включает в себя такие вещи, как Для просмотра ссылки Войди или Зарегистрируйся, усиление Для просмотра ссылки Войди или Зарегистрируйся или Для просмотра ссылки Войди или Зарегистрируйся (Для просмотра ссылки Войди или Зарегистрируйся). В этом посте мы попытаемся разобраться с распознаванием паролей.

Очевидно, что мы не первые, кто додумался до этого. Два года назад Том Калло из Для просмотра ссылки Войди или Зарегистрируйся опубликовал пост под названием Для просмотра ссылки Войди или Зарегистрируйся и соответствующий инструмент под названием Для просмотра ссылки Войди или Зарегистрируйся. Их подход был очень интересным и кратко выглядел следующим образом:



Процесс выполнения SharpML.​
Хотя в сообщении говорится: "Мы также выпустим отдельно [sic] некомпилированную модель машинного обучения и правила, с которыми вы сможете поиграть, и которые будут размещены на Github", на момент написания этой статьи этого еще не произошло. Не зная ни архитектуры модели, ни метрики производительности, ни того, как именно она обучалась (хотя, судя по репозиторию, я предполагаю, что она использовала Для просмотра ссылки Войди или Зарегистрируйся), я хотел воссоздать модель распознавания паролей и предоставить как можно больше деталей. Я также хотел избежать компонента проверки паролей в реальном времени, поэтому мне не нужно было беспокоиться о транспортировке и выполнении модели на произвольном хосте в целевой среде.

[EDIT 6/2/22] Том Калло вышел на связь через LinkedIn и сообщил, что возникли некоторые трудности с выпуском их конкретной модели, но он все еще планирует это сделать. Он также упомянул, что модель "не была обучена на 10 тыс. паролей, а фактически логически основана на KPI, относящихся к собственному руководству Microsoft по паролям", и что в ближайшее время у него должны появиться новые интересные работы!

Сразу оговорюсь: эта модель не идеальна, и я буду объяснять ее недостатки по ходу дела. На Для просмотра ссылки Войди или Зарегистрируйся есть сообщение о некоторых из этих трудностей, включая тему, о которой мы будем говорить здесь: "...самое сложное - это выяснить, как получить подходящие обучающие данные в достаточном объеме".



Если вы думали, что в этом посте вам удастся избежать мемов, подумайте еще раз.​
Jupyter Notebook и Docker-модель теперь публично доступны в Для просмотра ссылки Войди или Зарегистрируйся.

Проблема

Многие вещи в машинном обучении легче сказать, чем сделать. Когда я начинал изучать эту дисциплину, таинственность ML ощущалась примерно так же, как когда я начинал изучать наступательную безопасность: Я думал, что все возможно. Сейчас я по-прежнему считаю, что все возможно, но некоторые вещи определенно более возможны, чем другие.

Итак, какую именно проблему мы хотим решить?

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

Я собираюсь пропустить здесь тему автоперебора и сосредоточиться на том, как построить абстрактный API, в который мы можем отправить произвольный документ и получить обратно подходящую подборку паролей. С точки зрения архитектуры это обычный сценарий развертывания для ML-моделей, и я расскажу о его реализации в Docker в одном из следующих разделов.

Наш API должен:

  1. Принимать документы различных типов данных (.docx, .pdf, .pptx и т.д.).
  2. Извлекать из каждого типа документов слова, содержащие открытый текст (в лингвистике машинного обучения их часто называют токенами)
  3. Прогнать извлеченный текст через какую-либо модель машинного обучения
  4. Получить подборку вариантов паролей из результатов модели вместе с некоторым окружающим контекстом.
Прежде чем мы приступим к построению и обучению модели, снова возникает один из главных вопросов, упомянутый в сообщении StackExchange: как получить хорошие обучающие данные?

Проблема данных


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

Рассмотрим следующие предложения:

  • Чтобы войти в систему, используйте следующий пароль: Password123!
  • Мы сбросили ваши учетные данные на 'ChangeMePlz?', пожалуйста, измените их в будущем.
  • Учетные данные для базы данных - user:Qwerty123456.
Очевидно, что в документе почти всегда есть много сочного контекста, окружающего пароль, который поднимает большой красный флаг "ПАРОЛЬ!" при проверке документа. Однако, если мы хотим обучить прогностическую модель для этого конкретного набора проблем, нам нужны размеченные данные, причем в большом количестве, если мы не просто выполняем базовый поиск в стиле regex. Это означает, что нам нужно большое количество документов, аналогичных тем, с которыми мы могли бы столкнуться в реальной жизни, где мы знаем, что в подмножестве есть пароли, а в подмножестве паролей нет вообще. Мы не сохраняем данные клиентов после отчетности, и я не знаю ни одного общедоступного корпуса документов, который удовлетворял бы этим требованиям.



Разочарование от данных усиливается​
Мало что может быть более разочаровывающим в ML, чем вера в то, что вы могли бы решить проблему, если бы у вас только был нужный (несуществующий) набор данных.

Поэтому мой подход был идеей следующего лучшего, но не идеального подхода: Я сосредоточился на дифференциации самих паролей от "обычных" слов. Повторюсь, я знаю, что это не идеально, но это был лучший подход, который я мог придумать, учитывая ограничения. Относительная редкость паролей в тексте документа также создает проблему дисбаланса классов, о решении которой мы поговорим в последующих разделах. В английском языке: обучение модели для обнаружения относительно редких событий имеет свой собственный уникальный набор проблем!

В качестве исходного набора данных мне понадобилось большое количество паролей и непаролей. Для паролей я загрузил дамп Для просмотра ссылки Войди или Зарегистрируйся с CrackStation. Я случайным образом выбрал 2 000 000 паролей, состоящих из 7-32 символов, чтобы использовать их в качестве половины набора известных паролей.

Затем я прогнал большое количество Google dorks для поиска технических/IT-документов различных форматов, в итоге собрав ~1,300 публичных "подходящих по качеству" документов. Хотя в этих документах, возможно, содержатся пароли, обычный текст значительно превосходит все возможные отклонения. Я прогнал эти документы через Для просмотра ссылки Войди или Зарегистрируйся, известный инструментарий, который "...обнаруживает и извлекает метаданные и текст из более чем тысячи различных типов файлов (таких как PPT, XLS и PDF)" - я также буду использовать Tika позже в разделе о моделировании. Я выбрал 2 000 000 случайных слов/знаков из этого набора для половины набора данных с известными словами.

Модель

В своих предыдущих заметках я подробно описал использование различных архитектур моделей для нашего набора данных PowerShell AST с табличной обфускацией. Я также упоминал, что Для просмотра ссылки Войди или Зарегистрируйся. Для текста определенные типы нейронных сетей обычно превосходят другие подходы, такие как Naive Bayes или N-Gram, Для просмотра ссылки Войди или Зарегистрируйся. В данном случае, поскольку мы выполняем токенизацию символов отдельных слов, а не токенизацию слов всего документа, я экспериментировал с различными нейронными сетями. Это заняло приличное количество времени из-за набора данных в 4 000 000 слов, поэтому я не смог поэкспериментировать так много, как мне хотелось бы. Я уверен, что существует либо другая архитектура, либо по-другому выстроенный подход, который работает лучше, чем тот, что у меня здесь.

Я попробовал несколько архитектур, от стекированных LSTM до различных одномерных ConvNet (Для просмотра ссылки Войди или Зарегистрируйся). Лучшей результирующей архитектурой была 200-узловая двунаправленная сеть долговременной памяти (LSTM) с ручным слоем встраивания и небольшим отсевом:



Если это вы, прочитав последние несколько абзацев, я попытаюсь добавить немного контекста:



Я никак не могу полностью объяснить эмбеддинг токенов для нейронных сетей или двунаправленную архитектуру LSTM в этом посте, и я сомневаюсь, что многие хотят, чтобы я это сделал. Поэтому я дам краткое, высокоуровневое объяснение и несколько ссылок, если вам интересно.

Текст - это последовательные данные. В предложении важна последовательность слов, а в ситуации со словом (т.е. паролем), как у нас здесь, важна последовательность символов. Мы не можем рассматривать последовательности так, как мы рассматривали данные табличного/матричного типа, нам нужен другой тип модели. Здесь на помощь приходят LSTM.

LSTM - это особый тип архитектуры глубокого обучения, называемый рекуррентной нейронной сетью (RNN), которая была разработана для обработки различных типов данных о последовательности. Нейроны в RNN имеют цикл, который позволяет им "запоминать" информацию о данных в последовательности. LSTM - это усовершенствованная архитектура RNN, которая доказала свою эффективность при работе с текстовыми данными и была де-факто текстовой архитектурой до появления трансформеров несколько лет назад. Я специально использовал двунаправленную LSTM, которая обучает одну LSTM, работающую вперед, и одну, работающую назад, на входных последовательностях. Это помогает нам получить как можно больше информации о шаблоне пароля.

Ботаник: "Почему вы не использовали трансформеры??!" Ну, я думал об этом и немного поигрался, но почти все примеры трансформеров, которые я нашел, имеют дело с последовательностями слов, а не последовательностями символов. Я также не полностью убежден, что нейронное внимание - лучший инструмент для последовательностей слов-символов. Однако, позвольте мне повторить мое обычное заявление "я не эксперт и не слишком хорошо разбираюсь в математике", и что я полностью открыт для того, чтобы кто-то показал мне, что я не прав!

Для обучения я также использовал технику под названием Для просмотра ссылки Войди или Зарегистрируйся, чтобы предотвратить перебор. Глубокое обучение включает в себя несколько "эпох", когда весь набор данных обучается партиями/чанками, в которых все данные поступают в модель один раз за эпоху. Ранняя остановка используется для мониторинга определенных метрик производительности модели во время обучения и останавливает обучение, если производительность не улучшается после определенного количества эпох. Это помогает избежать переобучения.

Итак, как показала себя модель?



Вы, как читатель, надеюсь, не устали от моих мемов.​
На самом деле, очень хорошо, с accuracy почти 99%! Однако это все еще большая проблема из-за соотношения редких событий (например, слово в документе является паролем) благодаря нашему старому другу - Для просмотра ссылки Войди или Зарегистрируйся. Давайте рассмотрим упрощенный пример, чтобы понять, почему.

Допустим, мы загружаем 100 документов, каждый из которых в среднем состоит из 5000 слов, и в 10 из этих документов содержится один пароль. Это означает, что из 500 000 слов-кандидатов, которые мы собираемся обработать, только 10 являются паролями. Что дает нам точность 99%?

499 990 непаролей * 99% accuracy = 494990 истинно отрицательных непаролей + 5000 ложно положительных паролей

10 паролей * 99% accuracy = 0 ложно отрицательных непаролей, 10 истинно положительных паролей.


Скорее всего, мы отметим все пароли, но у нас также будет 5000 ложных срабатываний! Это большая проблема, схожая с проблемой ложных срабатываний, от которой страдают аналитики по обнаружению. Когда истинно положительный результат - это относительно редкое событие в большом наборе данных, например, пароль в документе или реальное вторжение на хост в большой сети, даже очень точные модели будут давать большое количество ложных срабатываний.




Часто при обучении модели на редких событиях сам набор данных является несбалансированным. То есть набор данных должен отражать распределение данных в реальном мире, как, например, частота паролей, описанная мной ранее. Существуют различные методы работы с несбалансированными наборами данных, такие как увеличение/уменьшение выборки классов, увеличение объема данных и т.д. Однако в нашем случае, благодаря тому, как мы сформировали набор данных, он идеально сбалансирован.

Для решения проблемы ложных срабатываний у меня было две идеи, с которыми я экспериментировал. Первая заключалась в изменении порога принятия решения о вероятности для вывода модели. Наша модель, с ее единственным сигмоидным выходным нейроном, выдает не жесткую метку "пароль" или "не пароль", а скорее вероятность того, что входное слово является паролем. В большинстве случаев мы используем порог в 0,5 для определения меток, при этом >=0,5 означает, что входное слово является паролем. Однако мы можем вручную настроить этот порог, возвращая только те результаты, которые имеют более высокую, скажем, 0,9, вероятность того, что это пароль. Одним из преимуществ здесь является то, что мы можем многократно корректировать порог после обучения модели.

Другим вариантом является Для просмотра ссылки Войди или Зарегистрируйся при обучении модели. Это изменяет функцию потерь, чтобы сильнее штрафовать неправильные классификации для определенного класса, что может изменить соотношение ложноположительных и ложноотрицательных результатов в зависимости от того, как все взвешено. Недостатком здесь является то, что после обучения модели на взвешенных классах, это нельзя изменить, как при корректировке порога. Однако в данном конкретном случае этот вариант превзошел пороговый, хотя при желании мы могли бы объединить эти подходы. В окончательной модели, которую я обучил, использовались веса классов .9/.1, которые сильнее штрафовали ложные срабатывания. Это подробно описано в блокноте Для просмотра ссылки Войди или Зарегистрируйся в репозитории DeepPass.

Для окончательной оценки я использовал модель с наилучшими показателями ранней остановки на тестовом наборе, чтобы получить приведенные ниже метрики производительности. Если вы не знакомы с confusion matrix или валидационными/тестовыми выборками, ознакомьтесь с моей Для просмотра ссылки Войди или Зарегистрируйся.

accuracy: 0,98997
precision: 0.99629
recall: 0.98358
F1: 0.98990




Confusion matrix для тестового набора.​​

Это определенно более управляемо, с 723 ложными срабатываниями из 400 000 сбалансированных входных слов. Ложные срабатывания и ложные отрицания неразрывно связаны между собой, и уменьшение одного из них приводит к увеличению другого. Использование методики придания весов классов для уменьшения количества ложных срабатываний означает, что количество ложных отрицаний, или потенциальных паролей, которые мы упускаем, увеличится! Однако я чувствовал, что этот компромисс необходим для того, чтобы подход мог быть использован. Я также проникся еще большим сочувствием к защитникам, которым приходится ежедневно сортировать огромное количество предупреждений : )

Развертывание модели

Итак, у нас есть отличная модель Keras LSTM, которая, похоже, отлично справляется с нашей задачей. Как мы на самом деле можем ее использовать?



О боже, это преследует мои сны.​
В соответствии с нашей целью разработки API, я решил использовать Docker, чтобы упаковать все вместе. К счастью для нас, существует официально поддерживаемый образ Для просмотра ссылки Войди или Зарегистрируйся, который мы можем использовать для репликации этапа извлечения текста, а TensorFlow (базовая структура для фреймворка Keras Deep Learning, который мы использовали) имеет потрясающий проект под названием Для просмотра ссылки Войди или Зарегистрируйся. TensorFlow Serving - это простое предоставление функциональности модели после обучения, и у него также есть Для просмотра ссылки Войди или Зарегистрируйся.

Последний шаг - создание небольшого приложения для обработки входных запросов и вызова всех частей. Кроме того, я хотел предоставить возможность вводить пользовательские regex-термины для поиска по тексту каждого документа, а также предоставлять несколько слов окружающего контекста для каждого результата. Весь этот код должным образом докеризован и размещен в Для просмотра ссылки Войди или Зарегистрируйся. Вот как выглядит (я знаю) крошечное фронт-энд пробного веб-приложения:



А вот пример результата:



Вся система, очевидно, может быть использована как прямой API на Для просмотра ссылки Войди или Зарегистрируйся.

Код:
C:\Users\harmj0y\Documents\GitHub\DeepPass>curl -F "file=@test_doc.docx" http://localhost:5000/api/passwords

Код:
 		[{"file_name": "test_doc.docx", "model_password_candidates": [{"left_context": ["for", "the", "production", "server", "is:"], "password": "P@ssword123!", "right_context": ["Please", "dont", "tell", "anyone", "on"]}, {"left_context": ["that", "the", "other", "password", "is"], "password": "LiverPool1", "right_context": [".", "This", "is", "our", "backup"]}], "regex_password_candidates": [{"left_context": ["for", "the", "production", "server", "is:"], "password": "P@ssword123!", "right_context": ["Please", "dont", "tell", "anyone", "on"]}], "custom_regex_matches": null}]

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

Заключение

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

Если вы хотите заново обучить модель с помощью другого набора данных, более подходящего для ваших операций, Jupyter Notebook в репозитории DeepPass покажет вам, как это сделать. Просто создайте новый dataset.csv со столбцами "word", "is_password", заново обучите модель, сохраните модель и замените ее в разделе ./models/ проекта Docker.


Примечание переводчика: часть терминов ни разу не слышал переводов в русском языке, то же состязательное машинное обучение или наступательное машинное обучение, но постарался перевести наиболее релевантным образом. Метрики производительности, они же метрики оценки качества модели обычно не переводятся.
source: posts.specterops.io/deeppass-finding-passwords-with-deep-learning-4d31c534cd00
 
Activity
So far there's no one here