Программисты просто не думают о безопасности, или Зачем в кофеварке Wi-Fi

12 березня 2018
Dmitry Andrianov, Senior Software Architect в DataArt
Программисты просто не думают о безопасности, или Зачем в кофеварке Wi-Fi
Какие угрозы таит быстрый вывод новых продуктов на рынок, нелепые ошиби разработчиков, способные подставить под удар любую систему, и почему на самом деле производители снабжают чайники Wi-Fi-модулями.

Кодить, забыв об опасности

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

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

Непреднамеренный вред

Айзек Азимов сформулировал три закона робототехники, первый из которых гласит: «Робот не может причинить вред человеку или своим бездействием допустить, чтобы человеку был причинен вред». Но сам же в романе «Обнаженное солнце» писал и о несовершенстве этих законов: они не защищают от непреднамеренного вреда — если один робот приготовит яд и поставит его в определенное место, а другой просто отнесет стакан с напитком хозяину, не зная о содержимом, вдвоем они вполне могут совершить убийство. Даже несмотря на то, что каждый из них в отдельности имеет фундаментальный запрет на это.

Классический пример такого дуэта в IT — вынос недостаточно защищенного сервиса в публичный интернет. Разработчик, который этот сервис написал, отдавал себе отчет, что тот, возможно, защищен достаточно примитивно, но он также знал, что это внутренний сервис, он находится в относительно безопасной сети, недоступен «снаружи». Проблема в том, что свое знание о возможных проблемах с безопасностью он никому не передал, а в через какое-то время новое задание получил уже другой человек. Например, компания, в которой сервис сделали, начала аутсорсить часть работы, и доступ к системе потребовался работникам извне. И вот уже сервер прощупывают сотни скриптов, ищущих уязвимости, делается brute-force подбор паролей, которые для маленького внутреннего сервиса, скорее всего, простые, наверняка и тестовые аккаунты остались, да и SSH-сервер без секьюрити-патчей за два года.

Кто тут самый виноватый? Здравый смысл подсказывает, что тот, кто выставил сервис в интернет — он не обеспечил его должную защиту. Но ведь он мог и не знать, что там есть аккаунт «admin» с паролем «test» или что по определенному URL разработчик оставил страницу диагностики, которая вообще не защищена паролем. Если бы первый разработчик не экономил на безопасности и делал систему «как для врагов» — может быть, многих проблем можно было бы избежать. Именно поэтому забота о безопасности должна начинаться с первого дня — это то, что называется «security in depth».

О таких вещах задумываются немногие, обычно программисты в своих действиях просто не видят «security implications». Не потому, что они глупые или ленивые, просто им никогда не приходилось иметь с этим дело. Вот аналогия — джуниор написал какой-то фрагмент программы, два дня его вылизывал и тестировал, он уверен, что теперь в нем все идеально. При этом синьору достаточно одного взгляда, чтобы увидеть баг в этом коде. Ему не нужно что-то тестировать и проверять — он просто сразу может сказать: «Вот тут при таких-то условиях оно сломается». Можно сказать, что «нейронная сеть» опытного разработчика гораздо лучше натренирована в этой предметной области и какие-то паттерны он просто «видит». Мгновенно, не задумываясь. При этом тот же самый опытный разработчик сам может в упор не заметить огромную дыру в безопасности, которую он только что создал. Его «нейронная сеть» отлично натренирована, но она натренирована на другие вещи, он просто «не видит» проблему. Если ее показать, он все поймет, часто с полуслова, но сам он уязвимость проморгает.

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

Buffer overflow

Я предполагаю, большинство разработчиков знают, что такое buffer overflow и почему, когда пишешь на языке C, нельзя использовать функции стандартной библиотеки, которые форматируют строчку, не ограничивая ее длину. Просто потому что в сервисе с открытой регистрацией какой-нибудь пользователь попытается создать себе имя такой длины, которая переполнит буфер и заставит процессор выполнять уже не ваши, а его команды. Это тема, казалось бы, заезжена. Об этой проблеме известно десятки лет, но на GitHub и сейчас можно найти какой-нибудь свежий opensource-проект, в котором первой же строчкой будет форматирование текста в не ограниченный по длине буфер, где в качестве параметров используется информация «out of control of the application, т. е. полученная от пользователя.

Мне кажется, индустрия уже потеряла надежду, что разработчики когда-то научатся защищаться от buffer overflow. Поэтому основное движение было в сторону того, чтобы сделать его невозможным — аппаратная защита от выполнения стека или вовсе отсутствие прямого доступа к памяти в высокоуровневых языках. Но хоть язык C неуклонно теряет популярность, он пока силен и по-прежнему почти безальтернативен для встраиваемых устройств и IoT, поскольку на слабенький процессор ничего больше не затолкаешь.

В Java такое слабое место, как buffer overflow, отсутствует как класс. Но каким бы ни был язык, не составляет труда накодить на нем какую-нибудь классическую дыру. Скажем, вроде сервера, возвращающего файл из upload-каталога по его имени, где окажется, что в имени можно передать ../../.. и выйти за пределы upload-каталога. Подобные проблемы известны много лет, и в 2018 году не должно быть ни одной программы, которая позволяет этим воспользоваться. Но они продолжают появляться.

Именно поэтому мне кажется важно обучать разработчиков безопасности. И самое главное, наверное, это как раз рассказывать им об „опасности“» — как обычно взламываются системы. Только с этим набором знаний они начинают видеть проблемы в своем коде.

Опасные связи

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

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

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

Готовность к стандартам, труду и обороне

Здорово, если умная лампочка, которую ты купил, сразу интегрируется с умным домом. Но с большой вероятностью она реализует какой-то запатентованный производителем собственный «стандарт» и работает только со своим приложением. Теоретически тебе бы могло потребоваться десять приложений, чтобы регулировать лампочки от разных производителей. Apple, Google, Amazon пытаются ввести стандартный API для управления домом, при использовании которого тебе вообще не важно, как именно реализовано конкретное устройство. Какое-нибудь приложение от Amazon может управлять любым из них, понять его тип и успешно выполнять функции интерфейса между пользователем и облаком.

В IoT особенно ярко проявляется стремление как можно скорее вывести на рынок новейшее гениальное устройство. Поэтому вопрос стандартов оказывается вторичен — если приложение может управлять устройством, производитель уже счастлив. Позже на него начинают сбоку прикручивать, например, интеграцию с Amazon Alexa, чтобы им можно было управлять голосом. Но это уже пример after thought (мысли вдогонку).

Имплементировать стандарты с самого начала было бы проще, но всегда ли производители в этом заинтересованы? Возможно, некоторые вендоры как раз и хотят, чтобы их устройства отправляли информацию именно в их же собственное облако, откуда они смогут ее извлечь и проанализировать. Например, если компания поставляет термостаты, очень интересно собрать статистику, когда пользователи их включают и выключают, какую температуру считают оптимальной. Это позволит оценить картину по отдельным регионам и выделить основные типы пользователей, которых наверняка окажется немного. Привычный для каждого из них режим можно предлагать вместе с термостатом в виде preset с понятными названиям: «офисный сотрудник», «фрилансер» и т. д. В итоге клиенты смогут сэкономить время, а возможно, и деньги (если preset идет с особым тарифным планом на электричество), просто опознав себя в одном из типов.

Слабое звено

Производители бытовой техники теперь стараются вывести в интернет любой новый прибор. Я с большим удивлением узнал, что микросхема ESP32 (есть еще и более ранние варианты, в том числе ESP8266) стоит меньше доллара. Она позиционируется как «system on chip with integrated Wi-Fi» — в принципе, это маленький процессор со встроенной памятью и Wi-Fi-модулем. Стоит копейки, да и размером тоже с монету. Какой соблазн для производителя микроволновой печи воткнуть в нее такую штуку! А сколько возможностей для утюга!

Никакую определенную цель они могут при этом и не преследовать, скорее, прощупывать почву. Здесь можно вспомнить историю с Apple watch — я практически уверен, что на момент выпуска первого устройства никто не знал, какая из его возможностей выстрелит. Apple бил из дробовика во всех направлениях сразу: и тебе идентификация, и contactless payments, и фичи для спорта — и то, и это, все, что приходит в голову. К третьему Apple watch у них наверное собралась какая-то статистика использования устройства и понимание его пользователей. Поэтому презентация третьей модели уже смотрится гораздо больше как презентация спортивного аксессуара, чем чего-то другого. Думаю, производители бытовой техники делают то же самое, пытаясь посмотреть на реакцию пользователей.

Зачем стиральной машине выход в интернет? Я вижу только один резон: она сможет сама себя диагностировать и сообщить в сервисную службу о том, что скоро сломается. Это, возможно, полезно. Но производитель расскажет о миллионе других несомненно необходимых вещей, которые можно делать с connected стиралкой — конечно же, ее можно дистанционно запустить с телефона (здравствуй, еще одно приложение).

Почему засилье connected (без нужды) устройств — это проблема?

Кофеварка тоже может сходить в интернет, чтобы узнать свежие цены на кофе или курсы валют. И хотя она не может рассказать о тебе слишком многого, кроме, пожалуй, режима владельца, с ней может возникнуть другая проблема: «Цепь настолько крепкая, насколько крепким окажется ее самое слабое звено». Я имею в виду, если ваша кофеварка будет взломана, под ударом окажутся еще 25 ваших unhackable устройств. Тот, кто сумеет взломать любую бытовую технику, подключенную к вашей сети, по большому счету войдет к вам домой и сможет там разгуляться. Такое уже было, правда, не с кофеваркой, а с чайником. Его производитель использовал чип со встроенным Wi-Fi, поддерживавший TELNET с дефолтным паролем. А зайдя в чайник, через пару команд можно было получить Wi-Fi-ключ. В общем и целом, чем больше разных устройств в доме, тем больше того, что называется attack surface — потенциальных мест для атаки.

Например, у какого-то устройства может быть механизм, подразумевающий автоматический трансфер данных конфигурации. Если одно из них выйдет из строя и будет заменено новым, первое просто передаст данные о локальном окружении: ключи, пароли, а новое не нужно будет мучительно конфигурировать. Но, если в это механизме есть дырки, проходящий под окном человек сможет заставить устройство передать эти данные и ему. Проблема в том, что пользователь, как правило, понятия не имеет, на что способно его устройство. У него может быть всего одна кнопка, оно может не уметь ничего умного, и common sense подсказывает нам, что и угрозы оно представлять не должно. А представьте, что оно принимает команды по Bluetooth, и в нем забыли отключить режим диагностики... А всегда ли вы готовы доверять результатам security testing производителей бытовой техники? Да и было ли оно?

Выводы

Вряд ли умные холодильники поработят нас в ближайшее время (за кофеварку не поручусь). Но вот лишиться всех паролей можно по милости самого примитивного датчика, установленного в вашей квартире. Параллельно с проблемой security, существует связанная, но не тождественная ей, проблема privacy. Умные дома наблюдают за своими владельцами, в конце концов сбор информации — одна из основных функций устройств, из которых эти системы состоят. Если данные в итоге оказываются не в тех руках, наблюдение автоматически превращается в шпионаж.

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