Re[26]: [UPD2] Безопасность ОС. Можно ли решить кардинально
От: maxkar  
Дата: 20.10.14 11:00
Оценка: 12 (1)
Здравствуйте, ononim, Вы писали:

M>>Вот так на условных переходах теги теряются. Так что нужно бы все условные переходы трейсить и навешивать теги от условия перехода. Чую, так просто от этого не отделаться будет. Расползутся теги от условного перехода по всему приложению. Вот посмотрит браузер на clipping area для вывода чего-нибудь со странички банка, и все, на всем UI-выводе будет висеть тег этого банка. Даже после того, как я закрыл все окна от него.

O>Почему на всем UI выводе?
А так принято в типичной архитектуре на данный момент. Есть UI-поток, в котором выполняются все операции с графикой. И стоит ему сделать что-нибудь условное (например, прочитать атрибут Visible на каком-нибудь виджете, зависящий от данных банка) и все — на IP есть тег. Скорее всего, очистка тега при выходе из метода поможет бороться с этой проблемой. Что-то подобное может быть и внутри видео-драйверов, например.


M>>Еще интересные темы с межпроцессным взаимодействием. Как тегируется новый процесс?

O>Сущность 'процесс' ортогональна тегированию. Вкратце — советую вам в этом контексте про процессы забыть.
Зачем забывать? Они связаны все с тем же специальным случаем: регистром IP. Набор инструкций для него очень специфичен и очень сильно отличается от инструкций работы с другими регистрами и памятью. Как минимум нужно рассматривать, что с ним происходит при создании нового процесса (наследуется или нет). Этот связано с удобством разработки и использования. И именно на межпроцессное взаимодействие я буду смотреть в первую очередь для поиска способов очистить данные от тегов.
Плюс с процессами/потоками связаны некоторые вещи, которые очень сложно смоделировать в модели "функциональная зависимость от данных". Например, зависимость от текущего времени (таймауты, таймеры). С обычной памятью и кодом (при линейном потоке выполнения) проблем как раз нет. Но "текущая точка выполнения программы" тоже является очень важными данными, через которую я и буду атаковать. Банальное "я закрыл сокет за минуту" и "я не закрывал сокет больше двух минут" может служить для передачи бита данных. Кстати, обратите внимание, даже _закрытие_ сокета является передачей данных. Не проблема, но интересный момент.


M>>Немного черной магии и данные извлекаются из "отсутствия данных". Чтобы с этим бороться, нужно либо анализировать как-то program flow и возможные affected vairables. Либо радостно развешивать теги на все псевдоглобальное, включая thread.sleep, сетевые взаимодействия и прочие источники, которые могут быть использованы для кражи данных. Но даже там я реализую sleep через большой цикл. И буду с интервалом ридеров пускать, а не ждать в самом ридере.

O>Код не разбирал, не очень есть время на это сейчас, отвечу по изложенному тексту.
O>Теги навешиваются на все, на самом низком уровне Прыгая по дереву абстракций вверх — от них не спрячешься.

Буду ждать, пока разберете. И теги не помогут Попробую пояснить, что за трюк там используется на более простом примере.
// Общая переменная.
var a : Int = 0;

// Где-то в коде:
if (condition) {
  a = 1;
}
// Интересное место, какие там теги и данные в a ?!
print(a);

Забавные вещи начинаются в момент печати a. Допустим, я вижу в результате печати 0. Вопрос — а зависело ли это значение от conditional или нет? Формально — не зависело. Не писалась она после условия, только читалась. А с точки зрения здравого смысла — зависела! Если бы condition было true, было бы напечатано 1.
Теперь допустим кто-то (не пользователь) читает a. Допустим, он видит там 0. Какую информацию он имеет? Если там 0, то condition был false. Но в качестве бонуса он знает еще, что на a нет тегов от condition! Поэтому можно смело делать любые действия. Если же там 1-ка, то condition был true, но на нас уже есть теги от condition. Это уже не проблема, ведь что-то подобное мы делали при записи a, сделаем то же самое и в этом случае:
//Переменная для результата
var b : Boolean = true;

if (a == 0) {
  b = false;
}
print(b);

Все почти так же. Теперь b == condition и ее можно где-то читать. При этом на b заведомо нет тегов от condition. Да, остаются вопросы о том, как обеспечить последовательность выполнений двух примеров и следующего читателя. Если контекст очищается при вызове метода, можно просто три метода последовательно вызывать. Если же IP не очищается при возврате из метода (или условного вызова), нужно смотреть межпроцессорное/межпоточное взайимодействие. Там я буду использовать глобальное время для обеспечения нужной последовательности. Ну и вообще любой способ обеспечить "последовательность выполненя" будет потенциальным вектором атаки.

Получается, что для учета "зависит ли значение от другого значения" (в императивной модели) нужно знать не только те команды, которые выполнились, но и те, которые _не выполнились_ (но могли выполниться). Иначе мы можем "частично очищать данные".

Решение этой проблемы тоже есть. Нужно отказываться от изменяемых переменных и писать в чисто функциональном стиле. Причем вообще без исключений. Т.е. нам нужен haskell или что-то подобное с монадами для представления явной зависимости данных от "последовательных действий". Причем, похоже, это нужно делать на уровне всей системы. Т.е. IO должен быть глобальным для компьютера (системы), а не для одного процесса. Иначе я вместо записи бита в переменную будт создавать или не создавать файл. А другой процесс будет проверять наличие файла.

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

O>Вообще моя предполагаемая архитектура если она имплементиться в хардваре — должна тегировать физическую память. Вообще всю, каждый байтик должен быть учтен.
А вопрос даже не в том, как это реализовать. Нужно показывать, что это стоит реализовывать. У меня есть сильные подозрения, что после открытия файла теги с этого файла распространятся по 90% приложения (через Instruction Pointer или IO monad) в течение пары минут. При такой скорости распространения практического смысла в тегировании каждой ячейки памяти нет, можно сразу на приложение вешать теги (да, да IP очень мешает). Поэтому нужно показывать, что можно сделать такую архитектуру, в которой можно эффективно ограничивать область распространения тегов. Это должно быть практично, причем как для маленьких приложений, так и для больших. Во всех разных моделях (UI, сервер и т.п.).

P.S. Забавный сценарий для размышления. Я кладу на экран две кнопки (в одно и то же место). В зависимости от условия, я убираю первую или вторую кнопку. В какой-то момент пользователь нажимает оставшуюся кнопку и я получаю информацию о том, какое же было значение. Формально идет только пользовательский ввод. Поможет ли здесь тегирование и если поможет, то как? (Вот так и появится тег данных на всем UI, как я и предполагал выше). А если это в виде игры оформить, вообще круто будет! Пользователь в процессе игры будет нам данные от тегов очищать. Процесс передачи system->user->system.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.