Ломаем зашифрованный диск для собеседования от RedBalloonSecurity. Part 0x02

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

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

LEVEL3

По традиции, я начну с короткого содержания раздела диска:

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

Наша подсказка выглядит вот так:

Ха-ха. Кто-то не был лучшим интерном. В конце подсказки лежит ссылка, которая ведет на сайт phrack. org. Этот сайт заблокирован во многих организациях. Он попадает под категорию malware/viruses, но там нету ни единого плохого бинарника. Это очень старый онлайн журнал, где умельцы пишут статьи о том как что-то взломать. Наша ссылка ведет на статью о написании ASCII шеллкода для ARM процессоров.

ASCII шеллкод

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

Первая часть отвечает за абьюз уязвимости. То есть, это код, который использует специальные механики, такие как buffer overflow, race condition, use-after-free и тд. для того, чтоб заставить систему исполнить вторую часть эксплоита.

В этот раз, я покажу файл level_3.html целиком. Ведь он гораздо меньше, чем на предыдущем уровне.

Отличия

На строке 24 мы видим, что адрес нашей функции printf грузится в регистр R3. Пока что не понятно, для каких целей мы это делаем, но это, уж поверьте, стоит держать в голове :)

Ну, вот и все. В остальном, программа почти идентична той, что мы имели на LEVEL2. Конечно, есть парочка непохожих вещей, но они выходят за рамки процесса взлома этого уровня.

Жалкие попытки

Меняем прошивку

Первая мысль была загрузить файл level_3.lod в дизассемблер, найти место, которое будет похожим на то, что я вижу в level_3.html, отредактировать пару значений, и залить прошивку обратно на диск. Я воспользовался Hopper Disassembler, и все таки нашел это место! Очень странно то, что каждая вторая строка кода была совсем не похожа на то, что я вижу в level_3.html. Возможно, это была какая-то контрольная сумма, или же логика прошивальщика seaflashlin_rbs работает специфичным образом. Так или иначе, чисто для тестов, я изменил парочку значений.

Но, когда я попытался прошить диск, утилита seaflashlin_rbs завершалась с ошибкой. И, после прошивки, мои изменения не применились.

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

Может потыкать железяку?

Немного погуглив, я понял что каждый чип (IC) имеет такую штуку как JTAG. Это своеобразный интерфейс для тестирования чипа. Через него можно отдать команду процессору остановить исполнение кода, и переключиться в debug-режим. С помощью openocd можно «транслировать» debug-режимы различных чипов, и вывести порт для gdb. А уже с gdb можно попросить процессор показать определенные участки памяти, да и вообще слить всю память, которая находится в рабочем пространстве процессора. Если мы совершим подобное, мы отыщем функцию generate_key в огромном дампе памяти, и по референсам сможем найти все ключи!

Для подобной манипуляции есть парочка нюансов:

Нужно знать какие ножки процессора отвечают за JTAG

Нужно понять каким образом настроить openocd

На тыльной стороне платы был 38-пиновый разьем. Я так понял, что этот разьем используется для тестирования платы в процессе производства. На нем и должен быть наш JTAG

В результате, картина моего подключения выглядела ужасно. Кое что было криво припаяно, кое что просто контактировало с платой без какой-либо пайки. Куча female-male-female. Но, блин, оно работало. Когда я запустил openocd, у меня получилось опознать чип!

К сожалению, конфигурация openocd была безвозвратно утеряна, но скриншот подключения остался.

Я увидел 3 ядра процессора (JTAG tap). По partnumber я даже нашел изображения этого чипа, и они выглядели похожими на тот, что мы имеем на плате. Оказалось, что это STMicroelectronics STR912.

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

Решаем по правильному

В конце концов я сдался, и понял, что этот уровень нужно решать как есть, без попыток обойти систему. Уж слишком много было подсказок насчет шеллкода, патч от keystone с предыдущего уровня никак не шел из головы, и этот комментарий на строке 23 «SP: %x» все не давал мне покоя. К тому же, этот комментарий есть в задаче от предыдущего уровня.

На что получил вот такой ответ:

То есть, как видите, затея с прыжком исполнения на стек вполне реальна!

Берем во внимание все манипуляции с SP в процессе generate_key. Что написано пером. ну вы поняли. Я распечатал LEVEL2 & LEVEL3 и вручную все расписал. К сожалению, фоток от LEVEL2 не осталось, поэтому будет кусок кода из level_2.html:

level_3.html

level_3.html

На LEVEL2 (level_2.html), в самом начале, на строке 18, мы уменьшаем значение в SP на 0х10 байт. На строке 133 мы завершаем функцию, при этом прибавляя 0х20 байт. Инструкция на строке 134

Делаем вот такую обратную математику:

0x002C7BB8 и есть значение в SP на момент старта функции generate_key. Теперь делаем расчеты из LEVEL3. Здесь, перед копированием вводимых символов, мы увеличиваем стек (отнимаем адрес) на 0х90 байт. Здесь уже применяем прямую математику:

Сдвиг на 1 байт не сработает поскольку мы имеем дело с little endian архитектурой. Помним, что наши инструкции имеют размер в 2 байта. Делая такой маленький сдвиг, мы рискуем «захватить» предыдущий символ «R» как инструкцию для процессора и наш шеллкод не сработает.

Сдвиг на 3 байта это именно то, что нам нужно.

Что же, нам осталось рассчитать количество вводимых в консоль символов таким образом, чтоб возврат из generate_key направил исполнение кода на адрес 0x002C7B2B. Помним, что на строках 138-140 из level_3.html мы увеличивали адрес стека на 0xA0 (160) байт. И, увеличивали еще на 4 байта когда снимали значение со стека в LR.

Тестим шеллкод

Чтобы что-то протестировать, нужно это сначала написать. Здесь нам и нужен keystone assembler о котором шла речь на LEVEL2. Это не простой компилятор. Кроме самого компилятора он предоставляет несколько С-шных библиотек. Мы можем написать ассемблерную инструкцию, передать ее как текстовый параметр в keyston-овскую функцию, и получить 2х, или 4х (Thumb или ARM) байтовый код операции (опкод).

Для этого, нужно собрать keystone. Что же, идем в репу https://github. com/keystone-engine/keystone, смотрим инструкцию по сборке и собираем.

Не забываем применить патч из LEVEL2.

Патч выглядит большим, но в нем у нас меняется всего навсего одна строка в файле llvm/keystone/ks. cpp. Патч был создан для какой-то старой версии keystone и в нем не совпадают номера строк. Нам прийдется отыскать похожее место в коде, и сделать изменения ручками. На момент написания этой публикации, это строка 305 (функция ks_open, кусок switch/case, условие параметров препроцессора KS_MODE_LITTLE_ENDIAN | KS_MODE_THUMB). Меняем с

Инструкция по сборке говорит нам, что нужен cmake. Метапакет build-essential обязательно должен быть установлен. Ставим все через apt get install.

Создаем папку build в корне keystone, переходим в нее, и запускаем скрипт билда с уровня директорий выше.

Дабы не ломать примеры, продублируем sample. c в, к примеру, lv3.c, и заменим его в Makefile:

Наш Makefile должен выглядеть вот так:

Собираем и запускаем.

Вот теперь красота. Правда только, в обратном порядке байт.

Неужели готово?

То есть, что мы получили? Мы ввели желаемую операцию, получили ее опкод, и теперь нам нужно проверить, пройдет ли этот опкод ASCII фильтр. Смотрим на опкоды, и идем вот сюда https://www. asciitable. com. Еще есть очень удобный конвертор https://www. rapidtables. com/convert/number/hex-to-ascii. html

В нашем примере, инструкция BX R3 имеет опкод 0x18 0x47. Судя по ASCII таблице, первая цифра это какой-то CANCEL. Я уж точно не введу такое в консоль. Второй символ 0х47 даже не смотрим. Эта операция не пройдет ASCII фильтр, и мы не можем использовать ее в шеллкоде.

А вот BX R7 имеет опкод 0x38 0x47. Судя по ASCII таблице это «8» и «G». Вот это будет работать, и мы можем написать такое в шеллкод.

Надеюсь, все поняли что такое ASCII фильтр, и чем мы тут занимаемся :)

Пишем

Первый

Сохраняем адрес pfintf в память, куда указывает R7

Подгружаем адрес printf из памяти в R5

Второй

Для всех дальнейших ключей нам надо сделать следующее. Здесь вы видите части из level_3.html, где ключи расставляются в регистры R1-R3:

Пробуем сделать второй ключ:

Сохраняем адрес pfintf в память, куда указывает R7

Подгружаем адрес printf из памяти в R5

Грузим второй ключ по правилам из level_3.html в R1

Делаем EORS с первым ключом из R0 и сохраняем в R1. Второй ключ готов

Сохраняем его в память, куда указывает R7

Подгружаем его в R0

Третий

Для третьего ключа, делаем похожее:

Опа! Инструкция на строке 5 не пройдет фильтр из-за символа «¢». Он хоть и имеет текстовое представление, но не входит в рамки ASCII. Если я введу его в консоль, мне моментально отобразится сообщение, мол, символ не верный, и покажет чистую строку приглашения:

Инструкция LDR R2, [R4, #8] делает оффсет от R4 на 8 байт, лезет по адресу в память, и сохраняет содержимое в R2. Хм, мы можем хитро выкрутиться, и прибавить к адресу в R4 4 байта, а потом лезть в память с таким же оффсетом как и для первого ключа (инструкция на строке 3 проходит ASCII фильтр как с R1, так и с R2).

Черт побери, из-за 0х04 мы не сможем использовать подобное. Включаем максимальную хитрость! Может прибавить 44, а потом отнять 40?

Вау! Должно сработать. Делаем парочку изменений:

Ну ничего себе! У нас получилось. Это наш третий ключик!

Четвертый

Идем по тому же пути:

Стоит оговориться, что наш шеллкод может быть еще круче. Мы можем сформировать format string типа «%s%s%s%s», разместить его где-то в памяти, передать его адрес через R0, а в остальные регистры расставить ключи. У нас целых 0x90 байт для шеллкода. Но, раз уж мы решили левел, двигаем дальше.

Финалочка. Прошив диск файлом final_level. lod мне открылся раздел диска с названием 1337. Мы очень близки к награде! Содержимое раздела:

Нам ничего не остается как ввести это в консоль диска. Результат смотрите на видео:

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

Точки и тире были очень различимы на графике. Таким образом я получил пароль от последнего файла. На pdf-ке был счастливый единорог на радужном фоне, координаты офиса ребят в NYC и email адрес компании для тех, кто решил диск. А также, приватный и публичный ключи от BTC кошелька с обещанной наградой. Я скачал биткоин клиент Electrum, и подписал транзакцию, которая перевела все 0.1337 BTC на мой кошелек. В наше время, без пруфов никуда. Поэтому, воть:

Эпилог

Друзья, этот диск по правде занял очень теплое место в истории моей жизни. И я был чертовски рад поделиться этой историей с вами. Это был невероятно долгий путь. Как в процессе взлома, так и в процессе переноса моих мыслей и воспоминаний в виде этой серии публикаций. Наверное, всех интересует вопрос, получил ли я работу в Нью Йорке. мне хочется сделать из этого тайну а-ля в фильме «Начало» Кристофера Нолана. Юла пускай крутится, а зритель. будет сам думать, во сне это, или наяву.

Хочу снова упомянуть пользователя @raven19. Статья блещет грамматикой благодаря ему.

Как самостоятельно исправить код ошибки 0x00000000 в операционной системе Windows?

Фото 1

0x00000000 — эта ошибка может возникнуть при запуске программ, игр, приложений. Возникновение происходит, когда запущенное приложение пытается получить доступ к закрытому участку памяти, а специальная функция DEP встроенная Windows блокирует его.

Варианты отображения сообщения

На экране пользователь может увидеть такую информацию: «Инструкция по адресу 0x000…. обратилась к …… Память не может быть read». В окне ошибки будет предложено два варианта решения: завершение приложения или его отладка.
Фото 2Также вариант проблемы может выглядеть так: «Инструкция по адресу 0x000…. обратилась к …… Память не может быть written». В этом варианте будет предложен аналогичный способ решения.
Фото 3В случае появления проблем при запуске игр, сообщение может выглядеть так:

Фото 4

Суть и причины ошибки 0x00000000

Фото 5

Оба варианта сообщения означают, что программа собиралась использовать доступ к закрытой памяти, но функция дала отказ, поэтому появился данный код ошибки. Чаще всего данная проблема встречается при использовании программы virtualbox, которая создает виртуализацию системы. Она пытается получить доступ к закрытым участкам памяти и блокируется функцией Windows.
Решить эту проблему можно несколькими вариантами, и подходят эти решения для всех версий Виндовс — 7, 8, 10.

Как ее исправить?

Способ №1

Данный способ является универсальным для всех версий Windows и достаточно простым:

Фото 6

Во вкладке существует два варианта работы DEP. Нам необходим второй вариант — включить DEP для всех программ и служб, кроме выбранных ниже. Теперь необходимо выбрать кнопку добавить и выбрать необходимые приложения которые будут находиться в списке исключений. Такие программы и будут работать без возникновения ошибки.

Способ №2

Второй способ — это проверка компьютера на антивирусы или полное отключения DEP.

Для начала следует обновить ваш антивирус до самой последней версии и провести полное сканирование пк. После чего можно попробовать в ручном режиме отключить функцию DEP:

Фото 7

Предотвращение выполнения данных — DEP — это в своем роде защитная функция Windows, которая стабилизирует работу компьютера. Поэтому отключение может вести к некорректной работе ПК, но если вовремя обновлять антивирус и хотя бы 2 раза в неделю проверять компьютер, то этого будет достаточно для стабильной работы и отсутствия подобных проблем.

Полезное видео

Наглядный процесс решения данной проблемы с программой Virtual Box вы можете посмотреть здесь:

Источники:

https://habr. com/ru/post/553858/

https://yakadr. ru/windows/oshibki/0x00000000-v-operatsionnoj-sisteme-windows. html

Понравилась статья? Поделиться с друзьями:
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: