О том, как взламывали запароленный мак с помощью Arduino и OpenCV. По мотивам статьи Брутфорсим EFI с Arduino.
История
Началось всё как обычно — у моего друга заблокировали Mac Air, уведя аккаунт. И если iPhone можно восстановить, то Mac заблокировался с концами. Обращение в техподдержку ни к чему не привело, в сервисном центре предложили разблокировать за 1000 рублей и 1 день. Правда, обнаружили брак материнской платы, который не позволил им это сделать.
Прочитав статью Брутфорсим EFI с Arduino, решили повторить опыт. Правда, не было дисплея, зато было две ардуины — Uno и Mega2560. И ноутбук, который не очень жалко на ~33 часа оставить перебирать пароль. Решили сделать перебор с преферансом и поэтессами — пусть автоматика следит за перебором, а мы пьем чай.
Описание проблемы
Для начала — коротко о том, что мы вообще решали. Этот раздел для тех, кто не хочет внимательно читать статью, на которую я ссылался.
Если у Вас угнали аккаунт Apple, взломщик может заблокировать Ваш Mac удаленно, поставив четырехзначный числовой пароль по своему выбору. После этого невозможно включить мак, не введя этот пароль, причем этот пароль можно вводить в двух различных местах — перед входом в учетку свою (там отображаются 4 пустых односимволных поля для ввода, закрываемых звездочками) и при попытке войти в UEFI (в этом случае отображается поле для ввода любого количества символов, тоже закрытых звездочками). Если вводить много раз неправильный пароль в 4 поля, то ввод блокируется сначала на 5 минут, потом на 10, и так до часа. Для перебора не очень подходит. В случае UEFI повторять ввод можно примерно каждые 12 секунд (чуть меньше, на самом деле). Если посчитать максимальное время перебора, получим 33,(3) часа перебора, без учета времени на ввод символов и «ввода». Не смертельно, в принципе. Кажется, Apple есть о чем задуматься в плане безопасности.
Нам, однако, такая халатность в выборе сложности пароля (или задержки между вводами) только на руку.
Отмечу, что при вводе правильного пароля ввод не блокируется вообще, то есть, эти ~12 секунд — не время на проверку пароля, а искусственная задержка. Похоже, что можно влезть куда-то за этой задержкой и перебирать гораздо быстрее. Мы так не делали, но идея интересная.
Disclaimer
Всё происходящее в этой статье было законно (ибо производилось со своим маком), направлено на борьбу с мошенниками, контактная информация которых уже ушла куда следует. Использование материалов этой статьи для неправомерных (а равно и правомерных) действий ни при каких обстоятельствах не является ответственностью автора или сайта. Всё, что Вы делаете, Вы делаете на свой страх и риск. Автор или сайт не несут ответственности ни за какой ущерб, прямой или косвенный, причиненный материалами статьи. Короче, кто не спрятался, я не виноват.
Как перебирать?
Автор статьи «Брутфорсим EFI с Arduino» предложил замечательный способ подбора пароля — Ардуино прикидывается USB-клавиатурой и последовательно перебирает пароли. Я не буду повторять все тонкости подхода, ссылка на статью выше. Я опишу, что мы решили сделать по-другому и почему
- Использовать компьютер постоянно. У нас не было дисплея, поэтому писать лог того, что было введено, было не по чему. Поэтому компьютер будет помнить, что вводилось
- Распознавать изображение на мониторе мака. Нам показалось относительно несложным проверять, не взломан ли мак до сих пор, и вводить пароли только если не взломан. Всё равно компьютер используется.
- Проверять, что введено именно четыре символа. Это было самым неожиданным изменением для нас. Обнаружилось, что иногда связка компьютер — ардуино — ардуино — мак вводила не все символы. Иногда пропускался ввод, и это было не очень страшно (можно добавить 3-4 ввода после пароля, они не мешают). Но иногда пропускались символы пароля. Почему — загадка. Решили смотреть на картинку и убеждаться, что все символы введены. Если нет — повторять ввод.
- Перебирать пароли в произвольном порядке. Пароли в статье перебирались от 0000 до 9999, нам это не понравилось. Всего скорее, злоумышленник выбрал пароль, далекий и от 0000, и от 9999, чтобы подбирающий помучался. Поэтому решили сделать рандомизированный перебор. Какую злую шутку это с нами сыграло, читайте дальше.
Давайте же к сути!
Перебираем по такой схеме:
- Компьютер формирует список паролей для перебора
- Компьютер проверяет, что мак всё еще заблокирован
- Компьютер отпарвляет очередной пароль ардуине Uno, которая, фактически, используется как USB<->SERIAL переходник и имеет простейшую программу, которая ничего не делает
- С Uno данные читает Mega по Serial1. Именно поэтому использовали порядок Uno -> Mega, а не наоборот
- Mega вводит данные в мак, считая себя клавиатурой.
- Компьютер проверяет, что введено 4 символа на экране. Если нет, пароль помечается как невведенный
- По той же схеме нажимается ввод
- Пока поле для ввода пароля не пусто, ничего не делаем
- Как только поле для ввода опустело, переходим на второй шаг.
Передача данных
Данные передавались через USB, становились serial, потом становились нажатиями клавиш. Ничего особенно интересного здесь не было, кроме потрянных символов. Путем отладки определили, что символы теряются на последнем этапе. То есть, символ с клавиатуры уходит, а в маке не регистрируется. Почему, осталось загадкой. Не стали разбираться, просто проверяли, что всё ввелось.
Распознавание замка
Пока мак заблокирован, рисуется замочек. Вот такой:
Давайте его искать с помощью OpenCV! Это же такое подходящее использование для микроскопа (на самом деле нет).
На удивление, OpenCV под .NET завелся с полпинка и двух NuGet пакетов (OpenCV.NET, OpenCV). Дальше немного кода.
lck = CV.LoadImage("D:\mac-unlock\lock.png", LoadImageFlags.Unchanged); //Load lock image file
Capture camera = Capture.CreateCameraCapture(-1); //Create camera object to capture image. Don't care about device index as the notebook has 1 camera device
var img = camera.RetrieveFrame(); //get camera image
IplImage res = new IplImage(new OpenCV.Net.Size(img.Width - tpl.Width + 1, img.Height - tpl.Height + 1), IplDepth.F32, 1); //Create image for matching results
OpenCV.Net.CV.MatchTemplate(img, lck, res, TemplateMatchingMethod.CorrelationCoefficientNormed); //Find lock image in camera image
double min, max;
OpenCV.Net.Point minloc;
OpenCV.Net.Point maxloc;
CV.MinMaxLoc(res, out min, out max, out minloc, out maxloc);
if (max < 0.88) //No lock image on the screen! Wow!
...
Этот простой код ищет изображение замка на экране. Находит отлично:
Зеленый прямоугольник — найденный замок. Никаких сложностей этот раздел не вызвал. OpenCV очень удивил и обрадовал.
Поле для ввода пароля
Если мы нашли замок на экране, можно поискать под ним поле для ввода пароля. Это делается относительно несложно при помощи обычной манипуляции пикселями изображения. Или делалось бы, если бы не камера. Есть две проблемы. Во-первых, разрешение камеры было 640*480, что ужасно для анализа. Во-вторых, при непостоянном освещении камера вела себя совершенно непредсказуемо. То что-то засвечивалось, то что-то пропадало. Вторую проблему решили стабильными условиями освещения, первую — привязкой к размерам в пикселях и фильтрами.
Итак, замок есть, можно найти его центр и пойти вниз, пока не встретим два пика яркости.
На рисунке — яркости пикселов под замком.
Найдя два максимума на достаточном расстоянии, можно взять центр между ними и идти влево (считаем, что поле ввода пароля горизонтально). Когда нашли яркий пиксел, либо закончилось поле ввода, либо наткнулись на звездочку.
itmages.ru/image/view/2285411/b7808366
Поле ввода. Зеленый — рамка замочка. Белый — линия вниз, по которой ищем два максимума. Красный — найденные максимумы и первый яркий пиксел слева по центру.
Теперь, если первый яркий пиксел слева достаточно «слева», то поле ввода пустое. Если достаточно «справа», то введены 4 символа. Калибровка нужна, однако.
Во время калибровки искалось положение яркого пикселя при пустом поле ввода, потом вводились 4 символа, и искалось положение яркого пикселя. Эти значения сохранялись и дальше использовались как эталонные.
На этом заканчивается часть по работе с изображением, да и вообще пора переходить к результатам.
Результаты
Замочек не найден! После 33 часов работы пароль был подобран. Несмотря на рандомизацию, правильным оказался пароль под номером 35 с конца. Значением пароля было 2605. Вероятность этого события составила 0.35%.
Литература, оборудование и код
В статье использованы:
Apple Mac Air
Lenovo Thinkpad T510
Arduino Uno (compatible)
Arduino Mega 2560 (compatible)
Литература:
Брутфорсим EFI с Arduino — отсюда взято всё о работе с Ардуино как с клавиатурой и о принципе блокировки мака. Спасибо автору!
Оф. сайт Arduino
Оф. сайт OpenCV
Код. Внимание, код ужасен! Он написан ad hoc и содержит следы экспериментов. Кроме того, он привязан к размерам моей камеры, поэтому может потребоваться модификация!
Вы можете делать с кодом всё, что угодно, если это не запрещено законом.
Автор: gurux13