Хабрахабр

[Перевод] Курс MIT «Безопасность компьютерных систем». Лекция 21: «Отслеживание данных», часть 1

Массачусетский Технологический институт. Курс лекций #6.858. «Безопасность компьютерных систем». Николай Зельдович, Джеймс Микенс. 2014 год

Computer Systems Security — это курс о разработке и внедрении защищенных компьютерных систем. Лекции охватывают модели угроз, атаки, которые ставят под угрозу безопасность, и методы обеспечения безопасности на основе последних научных работ. Темы включают в себя безопасность операционной системы (ОС), возможности, управление потоками информации, языковую безопасность, сетевые протоколы, аппаратную защиту и безопасность в веб-приложениях.

Лекция 1: «Вступление: модели угроз» Часть 1 / Часть 2 / Часть 3
Лекция 2: «Контроль хакерских атак» Часть 1 / Часть 2 / Часть 3
Лекция 3: «Переполнение буфера: эксплойты и защита» Часть 1 / Часть 2 / Часть 3
Лекция 4: «Разделение привилегий» Часть 1 / Часть 2 / Часть 3
Лекция 5: «Откуда берутся ошибки систем безопасности» Часть 1 / Часть 2
Лекция 6: «Возможности» Часть 1 / Часть 2 / Часть 3
Лекция 7: «Песочница Native Client» Часть 1 / Часть 2 / Часть 3
Лекция 8: «Модель сетевой безопасности» Часть 1 / Часть 2 / Часть 3
Лекция 9: «Безопасность Web-приложений» Часть 1 / Часть 2 / Часть 3
Лекция 10: «Символьное выполнение» Часть 1 / Часть 2 / Часть 3
Лекция 11: «Язык программирования Ur/Web» Часть 1 / Часть 2 / Часть 3
Лекция 12: «Сетевая безопасность» Часть 1 / Часть 2 / Часть 3
Лекция 13: «Сетевые протоколы» Часть 1 / Часть 2 / Часть 3
Лекция 14: «SSL и HTTPS» Часть 1 / Часть 2 / Часть 3
Лекция 15: «Медицинское программное обеспечение» Часть 1 / Часть 2 / Часть 3
Лекция 16: «Атаки через побочный канал» Часть 1 / Часть 2 / Часть 3
Лекция 17: «Аутентификация пользователя» Часть 1 / Часть 2 / Часть 3
Лекция 18: «Частный просмотр интернета» Часть 1 / Часть 2 / Часть 3
Лекция 19: «Анонимные сети» Часть 1 / Часть 2 / Часть 3
Лекция 20: «Безопасность мобильных телефонов» Часть 1 / Часть 2 / Часть 3
Лекция 21: «Отслеживание данных» Часть 1 / Часть 2 / Часть 3

Спасибо, что пришли на лекцию в этот особенный день перед Днем Благодарения. Джеймс Микенс: отлично, давайте начнем. Не стесняйтесь ссылаться на меня как на источник рекомендаций. Я рад, ребята, что вы так преданы компьютерной безопасности и уверен, что вы будете востребованы на рынке труда. Сегодня мы поговорим об отслеживании заражения Taint-tracking, в частности, о системе под названием TaintDroid, которая обеспечивает выполнение этого типа анализа информационных потоков в контексте смартфонов под управлением Android.

Идея заключается в том, что ваш телефон содержит много конфиденциальной информации — список контактов, ваш номер телефона, адрес электронной почты и все такое. Основная проблема, затронутая в лекционной статье, рассматривает тот факт, что приложения могут извлекать данные. Если операционная система и сам телефон не будут осторожны, то вредоносное приложение может быть в состоянии извлечь часть этой информации и отправить её обратно на свой домашний сервер, и сервер сможет использовать эту информацию для всех типов злополучных вещей, о которых мы поговорим позже.

Другими словами, мы должны предотвратить возможность передачи данных в качестве аргумента сетевых системных вызовов. В глобальном смысле статья о TaintDroid предлагает такое решение: отслеживать конфиденциальные данные по мере того, как они проходят через систему, и, по сути, останавливать их перед тем, как они будут переданы по сети. По-видимому, если мы сможем это сделать, то мы по существу можем остановить утечку прямо в тот момент, когда она начнёт происходить.

Причина в том, что эти разрешения не располагают правильной грамматикой, чтобы описать тот тип атаки, которую мы пытаемся предотвратить. Вы можете подумать, почему же традиционных разрешений Android недостаточно, чтобы предотвратить извлечение данных этого типа? Но сейчас мы говорим о том, что находится на другом семантическом уровне. Разрешения для Android обычно имеют дело с правами приложений записывать или считывать что-либо с конкретного устройства. Даже если приложению было предоставлено право считывать информацию или записывать данные в такое устройство, как сеть, может быть опасно позволять приложению читать или записывать определенные конфиденциальные данные на устройство, на взаимодействие с которым у него есть разрешение.

Гораздо проще говорить о том, получает ли приложение доступ к устройству или нет. Другими словами, используя традиционные политики безопасности Android, трудно говорить о конкретных типах данных. Возможно, мы можем решить эту проблему, используя альтернативное решение, я обозначу его звёздочкой.

На первый взгляд, кажется, что проблема устранена. Это альтернативное решение состоит в том, чтобы вообще никогда не устанавливать приложения, которые могут считывать конфиденциальные данные и/или иметь доступ к сети. Как вы думаете, в чём здесь подвох? Потому что если приложение не может делать одновременно обе эти вещи, оно либо не сможет добраться до конфиденциальных данных, либо может их прочитать, но не сможет отправить по сети.

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

Например, на прошлых лекциях мы рассмотрели, что кеш браузера, например, может способствовать утечке информации о посещении пользователем конкретного сайта. Если мы просто скажем, что собираемся предотвратить деятельность такого рода, то фактически запретим работу множества приложений в телефоне, что наверняка не понравится пользователям.
Здесь есть ещё одна проблема — даже если бы мы реализовали это решение, оно не предотвратит утечку данных через кучу различных механизмов сторонних каналов. Чуть позже мы ещё поговорим о сторонних каналах. Поэтому даже при осуществлении такой политики безопасности мы не сможем проконтролировать все сторонние каналы.

Например, что делать, если у одного приложения нет доступа в сеть, но оно может общаться со вторым приложением, у которого он есть? Предлагаемое решение не остановит сговор приложений, когда два приложения могут сотрудничать, чтобы сломать систему безопасности. Но даже если приложения не состоят в сговоре, то может существовать какой-то трюк, когда одно приложение может вынудить другие приложения случайно выдать конфиденциальные данные. Ведь возможно, что первое приложение может использовать механизмы IPC Android для передачи конфиденциальных данных приложению, имеющему разрешения сети, и это второе приложение сможет загрузить эту информацию на сервер.

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

Рассмотрим, что же на практике делают вредоносные приложения для «Андроид». Итак, мы очень обеспокоены тем, что конфиденциальные данные покидают телефон. Ответ – «да». Существуют ли в реальном мире какие-то атаки, которые можно предотвратить отслеживаем заражения Taint-tracking? Первое, что могут сделать вредоносные приложения – это использовать ваше местоположение или IMEI для рекламы или навязывания услуг. Вредоносные программы становится все большей проблемой для мобильных телефонов.

Например, вы находитесь недалеко от кампуса MIT, значит, вы голодный студент, так почему бы вам не навестить мою закусочную на колёсах, которая расположена совсем рядом? Вредоносное ПО может определить ваше физическое местоположение.

Его можно использовать для вашего отслеживания в разных местах, особенно в тех, где вы бы не хотели «засветиться». IMEI – это целое число, представляющее собой уникальный идентификатор вашего телефона. Таким образом, в природе существуют вредоносные программы, способные проделывать такие вещи.

Они могут попробовать украсть ваш телефонный номер или список контактов и попытаться загрузить эти вещи на удаленный сервер. Второе, что делают вредоносные программы – это крадут ваши личные данные. Это может быть нужно, чтобы выдать себя за вас, например, в сообщении, которое позже будет использоваться для рассылки спама.

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

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

Если это типичное приложение, то, наверное, мы бы смогли обезопасить его при помощи разрешений? Студент: это вредоносное ПО, которое нацелено на взлом именно ОС Android, или это просто типичное приложение?

Существует оба типа вредоносных программ. Профессор: это очень хороший вопрос. Я приведу вам пример, который касается не столько вредоносного ПО, сколько неосторожного поведения людей.
Есть популярная игра Angry Birds, вы заходите в App Store и ищите её в строке поиска приложений. Как оказалось, довольно легко заставить пользователей нажимать на разные кнопки. И многие люди предпочтут скачать это второе приложение, потому что оно может стоить дешевле оригинальной версии. Первой в результатах поиска вам будет выдана оригинальная игра Angry Birds, а во второй строке может находиться приложение Angry Birdss, с двумя s в конце. После этого «бум» — и вы на крючке у хакера! Далее при установке это приложение напишет, что после установки вы позволите ему делать то-то и то-то, и вы скажете: «конечно, без проблем!», потому что получили желанных Angry Birds за сущие копейки.

Но вы совершенно правы, когда предполагаете, что если модель безопасности Android корректна, то установка вредоносных программ будет целиком зависеть от глупости или наивности пользователей, которые предоставляют ей доступ к сети, например, когда ваша игра «Крестики – нолики» не должна иметь доступа к сети.

Это ужасно по многим причинам, не только потому, что ваш телефон рассылает спам, но и потому, что, возможно, вы платите за данные всех тех писем, которые отправляются с вашего телефона. Таким образом, вы можете превратить свой телефон в бота. К тому же аккумулятор стремительно разряжается, потому что ваш телефон постоянно занят отправкой спама.

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

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

Таким образом, Taint-tracking сам по себе не является достаточным решением для предотвращения ситуации, угрожающей захватом вашего телефона.

Как я уже упоминал, TaintDroid будет отслеживать всю вашу конфиденциальную информацию по мере ее распространения в системе. Давайте рассмотрим, как работает TaintDroid. Источники информации генерируют конфиденциальные данные. Так, TaintDroid различает то, что называется «источники информации» Information sources и «поглотители информации» Information sinks. Это может быть ваш список контактов, IMEI, все то, что может связать вас, конкретного пользователя, с вашим настоящим телефоном. Обычно это датчики — GPS, акселерометр и тому подобное. Это устройства, которые генерируют заражаемую информацию, называют источниками зараженных данных – Taint source.

В случае с TaintDroid главным поглотителем является сеть. В таком случае поглотители информации – это места, в которые не должны утекать зараженные данные. В системе более общего назначения, чем телефон, могут быть другие Information sinks, но TaintDroid предназначен для предотвращения утечек именно в сеть. Позже мы поговорим о том, что можно представить больше мест, куда утекает информация, но сеть занимает в TaintDroid особое место.

Это означает, что вы можете иметь не более 32 отдельных источников заражения. В TaintDroid для представления заражения Taint используется 32-битный битвектор.

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

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

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

В этом случае следует подумать о включении более сложной поддержки среды выполнения для обозначения большего пространства. Однако, как мы обсудим позже, если вы хотите предоставить программистам возможность контролировать утечку информации, то есть указать свои собственные источники заражения и свои собственные типы утечек, то 32-х бит может быть недостаточно.

Приведу простой пример. Грубо говоря, когда вы смотрите на то, как заражение протекает через систему, в общем смысле оно происходит справа налево. Если у вас есть какой-то оператор, например, вы объявляете целочисленную переменную, которая равна значению широты вашего местоположения: Int lat = gps.getLat (), то по существу вещь, расположенная справа от знака равенства, генерирует значение, которое имеет некую связанную с ней зараженность.

Так что зараза придет отсюда, с правой стороны, и пойдет сюда, влево, чтобы заразить эту часть lat. Так что будет установлен какой-то конкретный флаг, который говорит: «эй, это значение, которое я возвращаю, исходит из конфиденциального источника»! Однако виртуальная машина Dalvik использует этот регистровый формат на более низком уровне для создания программ, и это на самом деле то, как семантики taint реализованы в реальности. Вот как это выглядит на взгляд человека-разработчика, который пишет исходный код.

Например, вы можете представить, что у вас есть операция move-op, которая указывает на пункт назначения dst и источник srs. В таблице к одной из лекционных статей имеется большой список команд с описанием, как заражение влияет на эти типы команд. Как я уже сказал, заражение идет с правой стороны в левую сторону, так что в данном случае, когда интерпретатор Dalvik выполняет инструкции с правой стороны, он рассматривает метку taint параметра sourse и присваивает её параметру dst. В виртуальной машине Dalvik, на абстрактном вычислительном движке, это можно считать регистрами.

У нас имеется один пункт назначения dst и два источника: srs0 и srs1. Предположим, что у нас имеется ещё одна инструкция в виде бинарной операции binary-op, которая выполняет что-то вроде сложения. В этом случае, когда интерпретатор Dalvik обрабатывает эту инструкцию, он берёт taint из обоих источников, объединяет их и затем присваивает это объединение точке назначения dst.

В таблице приведены различные типы инструкций, которые вы увидите, но в первом приближении это наиболее распространенные способы распространения заражения в системе. Это довольно просто. Один из таких особых случаев связан с массивами. Давайте рассмотрим особо интересные случаи, которые упомянуты в статье.

При этом программа объявляет некоторый массив char upper [ ] который будет содержать заглавные буквы «А», «В», «С»: char upper [ ] = [«А», «В», «С»] Допустим, у вас есть команда char c, которая присваивает некое значение С.

Так что вы можете представить, что здесь имеется некий код char upperC, который говорит, что заглавные версии этих символов «А», «В», «С» соответствуют конкретным индексам в этой таблице: char upperC = upper [C] Весьма распространенная вещь в коде — это индексирование в массив, подобный этому, используя C напрямую, потому что, как мы все знаем, Керниган и Ричи учат, что в основном символы – это целые числа.

Кажется, что в предыдущих случаях у нас было всё просто, но в данном случае у нас много чего происходит. Здесь возникает вопрос, какое заражение должен получить upperC в данном случае. Здесь виртуальная машина Dalvik поступает похоже на то, как она поступала в случае binary-op. У нас есть массив [«А», «В», «С»], который может иметь тип заражения и у нас есть этот символ С, который тоже может иметь свой тип заражения. Она присваивает символу upperC сочетание заражений [C] и массива.

Мы должны что-то знать об этом индексе [C]. Интуиция подсказывает, что для создания upperC нам нужно знать кое-то о массиве upper [ ]. Поэтому я думаю, что эта вещь, upperC должна быть такой же конфиденциальной, как эти обе скомбинированные вещи.

Студент: можете ли вы еще раз объяснить, что именно означает объединение taint для операций move op и binary op?

Представим, что эта операция srs… вообще-то, позвольте мне уточнить. Профессор: давайте посмотрим на операцию перемещения move op. Представьте, что каждое из этих летающих вокруг значений имеет летающее вокруг него связанное целое число, в котором установлено несколько битов.
Предположим, что этот источник srs имел два набора битов, связанных с тем, что он был заражен двумя вещами. Каждая переменная, я сейчас расскажу, что такое эта переменная, представляет собой целое число, которое имеет кучу битов, установленных в соответствии с имеющимися taint. Так что это простой случай. Интерпретатор посмотрит на этот источник srs как на связанное целое число и скажет: «я должен взять это целое число, в котором установлены 2 набора битов, и сделать это число зараженным тегом для srs».

Представьте, что у нас есть два источника srs0 и srs1, и в каждом содержатся биты заражения taint, которые выглядят таким образом: Более сложный случай – это понять, как же выглядит это объединение taint.

\

Тогда пункт назначения dst будет содержать в себе все эти биты:

\

Таким образом, это действительно сокращает накладные расходы на реализацию этих зараженных битов. Как я уже сказал, одна из причин того, почему мы хотим представить все источники заражения в 32-х битах, заключается в том, что в данном случае мы просто совершаем побитовые операции. При этом upperC получит объединение битов из [C] и [«А», «В», «С»]. Если вам нужно отобразить более обширную вселенную taints, вы можете испытать большие затруднения, потому что уже не сможете использовать эти эффективные побитовые операции.
Итак, то, как работают массивы, немного похоже на обработку операции в случае binary-op. Другими словами, они пытаются не заразить отдельные элементы. Дизайнерское решение TaintDroid заключается в том, что разработчики связывают отдельную таблицу заражений taint с каждым массивом. Это позволяет им сэкономить место для хранения, потому что для каждого массива они объявляют только одну 32-х битную сущность, которая «плавает» вокруг этого массива и представляет все заражения, принадлежащие этому массиву.

Ведь массив — это набор данных, так почему бы нам не иметь кучу лейблов для каждой вещи, которая находится в этом массиве? Один из вопросов заключается в том, почему безопасно не иметь более точной системы для работы с taint. Другими словами, если у вас есть массив, содержащий внутри себя две вещи, и этот массив заражен объединением заражений этих двух вещей, то такой подход к проблеме является избыточным. Ответ заключается в том, что связывая только один тег taint с массивом и делая его объединением всех вещей, содержащихся внутри, мы получим переоценку заражения. Потому что если что-то получает доступ к одной из этих вещей, его не волнует заражение второй вещи.

Другими словами, если мы недооценим количество заражения, которое имеется в каком-то элементе, то случайно можем раскрыть то, что не хотели раскрывать. Однако избыточный подход предпочтительней недостаточного подхода, потому что в данном случае мы будем всегда правы. Так что в данном случае мы совершим ошибку в пользу безопасности. При переоценке заражения, худшее, что может случиться – это то, что мы предотвратим утечку за пределы телефона того, что можно было спокойно передавать по сети.

Native-методы могут существовать внутри самой виртуальной машины. Еще один пример, о котором упоминается в статье – это своего рода частный случай распространения заражения, при котором упоминаются такие вещи, как Native methods, или машинно-зависимые методы. Это один из примеров Native method, которым вы можете располагать. Например, виртуальная машина Dalvik предоставляет такие функции, как system.arraycopy(), так что мы можем что-либо передать через них, и внутри виртуальной машины по соображениям скорости это реализуется в виде кода C или C++.

JNI, или Java Native Interface — механизм для запуска кода на языке C или C++ на виртуальной машине Java. Ещё вы можете располагать машинно-зависимым методом под названием JNI. Данный интерфейс реализован с помощью x86, ARM или подобных вещей и имеет целую кучу вызовов, позволяющих взаимодействовать двум типам стеков. По существу, он позволяет коду Java вызывать код, который не является Java.

Часто это даже не Java-код, а C или C++ код. Проблема с этими машинно-зависимыми методами с точки зрения отслеживания taint заключается в том, что этот машинный код не может быть выполнен непосредственно интерпретатором Dalvik. Это означает, что как только исполняемый поток попадает в один из этих Native-методов, TaintDroid не может распространить заражения так, как он делает это в случае с кодом Java.

\

Способ, которым авторы решают эту проблему – это ручной анализ. Это кажется немного проблематичным, потому что эти вещи похожи на «черные ящики», и вы хотите убедиться, что в результате применения этих методов всё равно получатся новые taint. Например, виртуальная машина Dalvik предоставляет только определенное количество функций, подобных system.arraycopy(), так что разработчик может просмотреть на это относительно небольшое количество вызовов и выяснить, где должны быть отношения taint. По-существу они говорят, что здесь не так уж много этих методов. То есть разработчик может посмотреть на arraycopy() и сказать: «так как я знаю семантику этой операции, то я знаю, что мы должны заразить значения, возвращаемые этой функцией, задавая этой функции определенным образом входные значения».

Если существует относительно небольшое количество вещей, которые обрабатываются в виртуальной машине машинным кодом, у нас всё будет нормально. Каков же масштаб этого? Потому что, если вы предполагаете, что интерфейс виртуальной машины Dalvik меняется не очень часто, то на самом деле не слишком обременительно рассматривать все эти вещи вручную, изучать документацию и выяснять, как будет распространяться заражение.

Авторы статьи приводят некоторые эмпирические данные, которые свидетельствуют о том, что многие приложения не содержат кодов, написанных на C или C++, поэтому это не будет большой проблемой. Применение машинно-зависимого метода JNI может быть, а может и не быть более хлопотным делом.

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

26:25 мин

Лекция 21: «Отслеживание данных», часть 2 Курс MIT «Безопасность компьютерных систем».

Полная версия курса доступна здесь.

Вам нравятся наши статьи? Спасибо, что остаётесь с нами. Поддержите нас оформив заказ или порекомендовав знакомым, 30% скидка для пользователей Хабра на уникальный аналог entry-level серверов, который был придуман нами для Вас: Вся правда о VPS (KVM) E5-2650 v4 (6 Cores) 10GB DDR4 240GB SSD 1Gbps от $20 или как правильно делить сервер? Хотите видеть больше интересных материалов? (доступны варианты с RAID1 и RAID10, до 24 ядер и до 40GB DDR4).

VPS (KVM) E5-2650 v4 (6 Cores) 10GB DDR4 240GB SSD 1Gbps до января бесплатно при оплате на срок от полугода, заказать можно тут.

класса c применением серверов Dell R730xd Е5-2650 v4 стоимостью 9000 евро за копейки? Dell R730xd в 2 раза дешевле? Только у нас 2 х Intel Dodeca-Core Xeon E5-2650v4 128GB DDR4 6x480GB SSD 1Gbps 100 ТВ от $249 в Нидерландах и США! Читайте о том Как построить инфраструктуру корп.

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть