Текстовые строки: скрытая уязвимость встроенного ПО
Долгое время безопасность настольных компьютеров была главной проблемой. Как только машина подключается к интернету, появляется внутренняя возможность атаки. Такие вторжения могут направлены на кражу данных, повреждение системы или изменение её работы. Средства защиты хорошо известны и широко применяются. Встроенные системы казались невосприимчивыми к таким проблемам, так как они редко были в сети, а их код обычно находился в ПЗУ. Ситуация изменилась. Большинство современных систем подключены к интернету, а копирование кода в ОЗУ и выполнение оттуда стало обычной практикой. Это означает, что безопасность теперь является важным соображением при проектировании встроенного ПО.
Английский язык — отличный инструмент общения. Это очень выразительный язык, позволяющий передавать мысли с большой точностью и тонкостью. Однако в повседневной речи большинство из нас ленивы и часто используют слова без 100% точности. Пример, который я имею в виду — это использование слов safety (безопасность) и security (защита/информационная безопасность) почти как синонимов. Лучшее определение, которое я слышал, звучит примерно так: безопасность — это защита мира от устройства; защита — это защита устройства от мира. Сегодня моя тема — защита (security).
Если системе действительно необходима абсолютная неприступность, требуется промышленное шифрование. Обычно это требует специальной аппаратной поддержки, которая, хотя и доступна, может считаться избыточной для приложений, где такая высокая безопасность не нужна. В таких случаях существуют другие варианты, и именно их я хочу рассмотреть.
Если хакер получает доступ к содержимому памяти устройства, он может начать разбираться, что оно делает и как. Это первый этап изменения его работы. Код может быть дизассемблирован, и логика становится 드러нутой. Без шифрования мало что можно сделать для предотвращения этого. Следующее, что может сделать хакер — просмотреть шестнадцатеричный/ASCII-дамп данных и найти там что-то осмысленное. Он ищет шаблоны и узнаваемые структуры. И здесь можно принять некоторые меры предосторожности. Если шифрование не является вариантом, обфускация становится возможностью.
Цель обфускации данных — задержать или отвлечь хакера, просто делая данные менее узнаваемыми. Просматривая дамп памяти, одной из легких для обнаружения вещей являются текстовые строки. Поэтому я сфокусируюсь на них.
В коде на C/C++ текстовые строки обычно представляют собой просто последовательности байтов, содержащих ASCII-коды, завершаемые нулевым байтом. Это очень легко обнаружить, поэтому я это изменю. Во-первых, вместо нулевого терминатора первый байт каждой строки будет спецификатором длины. Символы строки будут немного перемешаны, чтобы они выглядели менее привычно — я просто поменяю местами два тетрада (полубайта) каждого байта. Мне нужна утилита, в которую я бы подавал открытые текстовые строки, а она генерировала объявление массива с соответствующей инициализацией. Вот функция в центре этой утилиты:
void scramble(int index, unsigned char *input) { unsigned char *charpointer, character; printf("unsigned char string%d[%d] = {0x%02x,", index, strlen(input)+1, strlen(input)); charpointer = input; while(*charpointer) { character = *charpointer++; character = ((character & 0x0f) << 4) | ((character & 0xf0) >> 4); printf("0x%02x", character); if (*charpointer) printf(","); } printf("}; // \"%s\"\n", input); }
Если я передам этой функции индекс 4 и строку «Hello world» (оригинально, да?), вывод будет:
unsigned char string4[12] = {0x0b, 0x84, 0x56, 0xc6, 0xc6, 0xf6, 0x02, 0x77, 0xf6, 0x27, 0xc6, 0x46}; // "Hello world"
Я могу скопировать и вставить это в свой код, затем мне нужно только написать функцию для расшифровки текста при необходимости его отображения. Вместо присвоения каждой строке индексного номера я мог бы дать ей произвольное имя, заменив параметр index строкой. Обратите внимание, что сгенерированный код в некоторой степени самодокументируем, так как комментарий показывает строку в читаемом виде, но, конечно, это появляется только в исходном коде. Если у хакера есть доступ к вашему исходному коду, вы в достаточной беде, и я не смогу помочь дальше!
Вот код, иллюстрирующий процесс расшифровки:
void main() { unsigned char temp, buffer[50]; int count = string4[0], index=0; while(count--) { temp = string4[index+1]; temp = ((temp & 0x0f) << 4) | ((temp & 0xf0) >> 4); buffer[index] = temp; index++; } buffer[index] = 0; printf("-%s-\n", buffer); }
Обмен тетрад в каждом байте — один из множества способов перемешивания. Другой вариант — например, циклический сдвиг каждого символа влево на три бита. Вот код для этого:
unsigned char leftrotate3(unsigned char c) { c = (c << 3) | (c >> 5); return c; }
Описанные техники обфускации перемешивают строку посимвольно. Можно было бы делать вещи со всей строкой сразу. Например, рассматривать строку как длинную последовательность бит и циклически сдвигать её на произвольное число влево. Кодирование этого алгоритма оставлю более энтузиастичному читателю.
Стоит отметить, что побочным эффектом локализации всех текстовых строк является то, что создание различных версий ПО для других языков становится довольно простым.
Я должен повторить и подчеркнуть: обфускация данных далеко не пуленепробиваема и в лучшем случае лишь замедлит серьезного хакера. Если ничего больше, код расшифровки может быть дизассемблирован. Трюк этой техники — сделать обфускацию сложным для следа. Если вам нужна реально большая безопасность, вы должны смотреть в сторону полного шифрования.
Встроенный
- Фортепиано: от древних корней к современному мастерству
- Как встроенные системы двигают инновации в современном автомобиле
- Основы встроенных систем и реальные применения
- 10 обязательных функций, которые должен предлагать софт для рабочего процесса 3D-печати
- SOAFEE: облачная-родная архитектура, уполномачивающая программно-определяемые автомобильные платформы
- Использование DevOps для преодоления сложностей встроенного ПО
- Роботы трансформируют ваш завод: что нужно знать
- Встроенное ПО перестраивает цепочки поставок оборудования для большей гибкости
- Взаимосвязь программного обеспечения: ключевые преимущества для умных заводов
- Как ПО для управления объектами улучшает работу религиозных организаций