Белое исследование взлома паролей с помощью машинного обучения
Предисловие
Не так давно считалось, что научить компьютер отличать кошек от собак - это было одним из самых современных исследований. Теперь классификация изображений - это «Hello World» машинного обучения (ML), что можно реализовать всего несколькими строками кода с помощью TensorFlow. Фактически, всего за несколько коротких лет область машинного обучения продвинулась настолько далеко, что сегодня с такой же легкостью можно создать потенциально спасающее жизнь или смертельное приложение. Таким образом, возникла необходимость обсудить как использование технологии, так и злоупотребление ею, в надежде, что мы сможем найти способы смягчить или защитить от злоупотребления. В этой статье я расскажу об одном потенциальном злоупотреблении этой технологией - взломе паролей с помощью машинного обучения.
Чтобы быть более конкретным (см. Рис. 1), можем ли мы выяснить, что кто-то набирает, просто слушая нажатия клавиш? Как вы понимаете, это имеет серьезные последствия для безопасности, например, взлом паролей.
Итак, я работал над проектом под названием kido (= декодирование нажатия клавиш), чтобы выяснить, возможно ли это (https://github.com/tikeswar/kido).
Наброски
Это можно рассматривать как проблему контролируемого машинного обучения, и мы рассмотрим все шаги.
- Сбор и подготовка данных
- Обучение и оценка
- Тестирование и анализ ошибок (повышение точности модели)
- Выводы; Ссылка на GitHub
Для этого проекта использовались Python, Keras и TensorFlow.
Сбор данных
Первый шаг - как собрать данные для обучения модели?
Есть много способов сделать это, но чтобы доказать, работает эта идея или нет, я использовал клавиатуру MacBook Pro для набора текста и QuickTime Player для записи звука набора текста через встроенный микрофон (рис. 2).
У этого подхода есть несколько преимуществ: 1. данные имеют меньшую изменчивость и, следовательно, 2. он помогает нам сосредоточиться на доказательстве (или опровержении) идеи, не отвлекаясь.
Подготовка данных
Следующим шагом является подготовка данных, чтобы мы могли передать их в нейронную сеть (NN) для обучения.
Quicktime сохраняет записанный звук в формате mp4. Сначала мы конвертируем mp4 в wav, так как есть хорошие библиотеки Python для работы с файлами wav. Каждый всплеск в правом верхнем подграфике соответствует нажатию клавиши (см. Рис. 3). Затем мы разбиваем звук на отдельные фрагменты, используя обнаружение тишины, чтобы каждый фрагмент содержал только одну букву. Теперь мы могли бы скормить эти отдельные куски сети, но есть лучший подход.
Преобразуем отдельные фрагменты в спектрограммы (рис. 4). И теперь у нас есть изображения, которые намного информативнее и с которыми проще работать с помощью сверточной нейронной сети (CNN).
Для обучения сети я собрал около 16 000 образцов, как описано выше, убедившись, что каждая буква содержит не менее 600 образцов (рис. 5).
Затем данные были перемешаны и разделены на наборы для обучения и проверки. В каждой букве было около 500 обучающих образцов + 100 проверочных образцов (рис. 6).
Итак, вкратце, это проблема машинного обучения, которая у нас есть… см. Рис. 7.
Обучение и проверка
Я использовал довольно небольшую и простую сетевую архитектуру (основанную на примере« камень-ножницы-бумага Лоуренса Морони»). См. Рис. 8 - входное изображение масштабируется до 150 x 150 пикселей и имеет 3 цветовых канала. Затем он проходит через серию слоев свертки + объединения, выравнивается (используется выпадение для предотвращения чрезмерной подгонки), подается на полностью подключенный слой и выходной слой в конце. Выходной слой имеет 26 классов, соответствующих каждой букве.
В TensorFlow модель выглядит так:
model = tf.keras.models.Sequential([ # 1st convolution tf.keras.layers.Conv2D(64, (3,3), activation='relu', input_shape=(150, 150, 3)), tf.keras.layers.MaxPooling2D(2, 2), # 2nd convolution tf.keras.layers.Conv2D(64, (3,3), activation='relu'), tf.keras.layers.MaxPooling2D(2,2), # 3rd convolution tf.keras.layers.Conv2D(128, (3,3), activation='relu'), tf.keras.layers.MaxPooling2D(2,2), # 4th convolution tf.keras.layers.Conv2D(128, (3,3), activation='relu'), tf.keras.layers.MaxPooling2D(2,2), # Flatten the results to feed into a DNN tf.keras.layers.Flatten(), tf.keras.layers.Dropout(0.5), # FC layer tf.keras.layers.Dense(512, activation='relu'), # Output layer tf.keras.layers.Dense(26, activation='softmax') ])
и краткое изложение модели:
_________________________________________________________________ Layer (type) Output Shape Param # ================================================================= conv2d_4 (Conv2D) (None, 148, 148, 64) 1792 _________________________________________________________________ max_pooling2d_4 (MaxPooling2 (None, 74, 74, 64) 0 _________________________________________________________________ conv2d_5 (Conv2D) (None, 72, 72, 64) 36928 _________________________________________________________________ max_pooling2d_5 (MaxPooling2 (None, 36, 36, 64) 0 _________________________________________________________________ conv2d_6 (Conv2D) (None, 34, 34, 128) 73856 _________________________________________________________________ max_pooling2d_6 (MaxPooling2 (None, 17, 17, 128) 0 _________________________________________________________________ conv2d_7 (Conv2D) (None, 15, 15, 128) 147584 _________________________________________________________________ max_pooling2d_7 (MaxPooling2 (None, 7, 7, 128) 0 _________________________________________________________________ flatten_1 (Flatten) (None, 6272) 0 _________________________________________________________________ dropout_1 (Dropout) (None, 6272) 0 _________________________________________________________________ dense_2 (Dense) (None, 512) 3211776 _________________________________________________________________ dense_3 (Dense) (None, 26) 13338 ================================================================= Total params: 3,485,274 Trainable params: 3,485,274 Non-trainable params: 0
Результат обучения показан на рис. 9. Примерно за 13 эпох он сходится к 80% точности проверки и 90% точности обучения. Я был приятно удивлен получением такого уровня точности, учитывая сложность проблемы и простую используемую сетевую архитектуру.
Результат пока выглядит очень многообещающим ... но учтите, что это точность на уровне символов, а не на уровне слов.
Что это обозначает? Чтобы угадать пароль, мы должны правильно угадать каждый символ, а не только большинство из них! См. Рис.10.
Тестирование
Итак, чтобы протестировать модель, я оцифровал еще 200 различных паролей из списка rockyou.txt, а затем попытался предсказать слова, используя только что обученную модель (рис. 11).
Рис. 12 показывает точность теста. Гистограммы показывают точность на уровне символов (левая диаграмма показывает количество правильных и неправильных, а правая диаграмма показывает то же самое в процентах). Точность теста составляет около 49% для уровня символа и 1,5% для уровня слова (сеть полностью вернула 3 из 200 тестовых слов).
Учитывая сложность задачи, точность на уровне слов 1,5% - это неплохо! Но можем ли мы повысить точность?
Анализ ошибок
Давайте проанализируем отдельные ошибки и посмотрим, есть ли способы повысить точность прогнозов.
На рис. 13 показаны результаты некоторых типовых испытаний. Первый столбец содержит фактические тестовые слова, средний столбец содержит соответствующие предсказанные слова, где отдельные символы имеют цветовую кодировку, чтобы показать правильные (зеленый) и неправильные (красный) предсказания. В третьем столбце отображаются только правильно предсказанные символы, а неверно предсказанные символы заменены подчеркиванием (для упрощения визуализации).
Для слова «aaron» наша модель соответствует едва ли одному символу, для «canada» - правильно улавливает большинство символов, а для «lokita» - все символы правильно. Как показано на рис. 12, точность на уровне слов составила всего 1,5%.
Прищурившись, взглянув на тестовые примеры (рис. 14), особенно на слово «канада», мы понимаем, что он правильно передает большинство символов и очень близок к фактическому слову. Итак, что, если мы передадим результат CNN через проверку орфографии ?!
Это именно то, что я сделал (рис. 15), и, конечно же, это повысило точность с 1,5% до 8%! Таким образом, с помощью довольно простой модели архитектуры + проверки орфографии мы можем правильно предсказать 8 паролей из 100… это нетривиально !!
Я думаю, если мы будем использовать модель последовательности (RNN ?, Transformer?) Вместо простого средства проверки орфографии, мы сможем получить еще более высокую точность на уровне слов… и это может быть темой для дальнейших исследований.
Но давайте еще более внимательно посмотрим на результаты теста (рис. 16). Мы замечаем, что «a» предсказывается как «s», «n» как «b» и т. Д.
Так что, если мы сопоставим ошибки на клавиатуре? И как только мы нанесем это на карту (см. Рис. 17), коррелирует ли ошибка с близостью? Это выглядит как!
Далее, можем ли мы количественно оценить корреляцию этой ошибки с близостью?
На рис. 18 показана клавиатура MacBook Pro с микрофоном и расположение клавиш в масштабе. На рис. 19 показаны карты ошибок на цифровой клавиатуре для некоторых образцов букв.
На рис. 19 левый верхний график показывает, что «a» ошибочно предсказывается как «z», «x», «y», «k», «s», «w» или «q». Остальные подсюжеты интерпретируются аналогично.
Рис. 19 дает более четкое указание на то, что ошибка может быть связана с близостью. Однако можем ли мы получить еще более количественную оценку?
Пусть d_ref
будет расстоянием от контрольной буквы до микрофона, d_predicted
будет расстоянием от предполагаемой буквы до микрофона, а d
будет абсолютным значением разницы между d_ref
и d_predicted
(см. Рис. 20).
На рис.21 показана гистограмма количества ошибок, разделенных на интервалы относительно. d
. Мы видим очень четкую тенденцию - большинство ошибок происходит в непосредственной близости! Это также означает, что мы, вероятно, сможем повысить точность модели за счет большего количества данных, большей сети или сетевой архитектуры, которая может лучше это уловить.
Но как насчет расположения микрофона - связана ли ошибка с тем, насколько далеко от микрофона находится клавиша? Чтобы исследовать это, график% ошибок на рис. 12 был перестроен таким образом, чтобы буквы на оси x располагались в порядке возрастания расстояния от микрофона (см. Рис. 22). Здесь не наблюдается сильной корреляции с. d_ref
, что указывает на то, что ошибки не зависят от местоположения микрофона.
На рис. 22 подчеркивается очень важный момент - микрофон можно разместить где угодно, чтобы слушать нажатия клавиш и иметь возможность взламывать! Жутко!
Улучшения модели
Для этого исследования я сделал некоторые упрощения, чтобы увидеть, работает ли идея взлома, просто слушая нажатия клавиш. Ниже приведены некоторые мысли по улучшению модели для обработки более сложных и реальных сценариев.
- Нормальная скорость набора текста → Сложная обработка сигнала (для выделения отдельных нажатий клавиш). - Для этого исследования я медленно печатал по одной букве за раз.
- Любые нажатия клавиш → Сложная обработка сигнала (Caps Lock on ?, Shift ?,…). - Для этого исследования я использовал только строчные буквы (прописные буквы, цифры, специальные символы, специальные нажатия клавиш и т. Д. Не использовались).
- Фоновый шум → Добавить шум. - Для этого исследования во время записи данных в некоторых случаях присутствовал простой и легкий фоновый шум проезжающих автомобилей, но не было сложного фонового шума (например, фонового шума кафетерия).
- Различные настройки клавиатуры и микрофона + разные люди, набирающие текст → Больше данных + увеличение объема данных + большая сеть + другая сетевая архитектура могут помочь улучшить модель.
- → Можем ли мы использовать другие сигнатуры вибрации вместо звуковой сигнатуры?
Выводы
Принимая во внимание упрощения, сделанные для этого исследования,
- Вроде можно взломать звуки нажатия клавиш
- Имея довольно небольшой объем данных и простую архитектуру CNN + проверку орфографии, мы можем получить нетривиальную точность на уровне слов (8% в этом исследовании).
- Анализ ошибок
* Простая проверка орфографии может повысить точность на уровне слов (в данном случае с 1,5% до 8%)
* Ошибки коррелируют с близостью к другим клавишам
* Кажется, что ошибки не зависят от расположение микрофона
Ссылка на GitHub: https://github.com/tikeswar/kido
—
пс. Следите за нажатием клавиш, у стен есть уши!