Хабрахабр

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

Массачусетский Технологический институт. Курс лекций #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

Студент: сейчас во многих приложениях отсутствует возможность удалять разрешения.

Но вы можете использовать Android Permission Manager, или менеджер разрешений «Андроид», который позволяет вам просмотреть список всех разрешений для каждого приложения и удалить конкретно те, которые вы считаете ненужными. Профессор: да, в новой версии Android этого нет, просто имеются описания разрешений. Но я не знаю, насколько эта вещь популярна среди пользователей.

Студент: если метки не совпадают с разрешениями, которые требует приложение, это приводит к серьезной ошибке или всё продолжает работать нормально?

Например, если приложение собирается отправить Intent и отправка этого намерения требует наличия определённой метки типа DIALPERM, то сначала оно обращается к монитору ссылок, который говорит: “к сожалению, в системе нет приложения, которое готово принять ваше сообщение». Профессор: я думаю, это зависит от того, что именно пытается сделать приложение и что разрешает сделать метка. И в ответ на это приложение предпринимает какие-то разумные шаги.

Если у вас нет доступа к сети, а вы собираетесь открыть сокет или отдаёте команду подключиться к IP-адресу, то ядро ответит вам сообщением EPERM, «операция не разрешена», то есть вы не можете этого сделать. Иначе происходит, например, при обращении к сети. Возможно, что оно каким-то образом выдаст исключение нулевого указателя или сделает что-то в таком роде. И кто знает, что в таком случае приложение собирается делать?

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

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

Но кто определяет эти строки, откуда они черпают смысл? Итак, мы рассмотрели, откуда берутся эти строки в метках приложений «Андроид». Кто придаёт им значение в системе? Вы может перечислять все виды строк в файле манифеста, но как вы решаете, какие строки имеют значение, откуда берутся строки INTERNET или FRIENDVIEW?

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

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

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

Что ещё связано с меткой в Android, кроме того факта, что она используется приложением, когда ему необходимо запросить разрешение? Что это означает? Кроме строки, метка обладает несколькими интересными свойствами. Выясняется, что есть несколько вещей, которые связаны с меткой. Первый – разрешения обычного типа, второй – небезопасные разрешения и третий тип– это подписанные разрешения. В частности, в Android существует 3 типа меток.

Так что это за типы меток? Приложение, которое определяет это разрешение, в первую очередь получает возможность выбрать тип и все другие поля для метки, о которых мы будем говорить через секунду. Зачем меткам Android нужны типы?

Студент: они служат предупреждением пользователю?

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

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

Если приложение хочет изменить обои рабочего стола, система спросит вас, хотите ли вы сменить обои. Студент: но эти разрешения обычно требуют от вас подтверждения, верно?

Профессор: нет.

Студент: нет?

Если я имею это разрешение, я просто делаю вызов API. Профессор: нет, оно просто изменит обои, потому что это просто доступ к вызову API.

Студент: может быть, разработчик приложения хочет убедиться, что пользователи не сделают этого случайно?

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

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

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

Интересным свойством Android является возможность предоставить доступ только тем приложениям, которые подписаны той же цифровой подписью, что и приложение, в котором объявлено право доступа. Третий тип меток — это разрешение на подпись. Если просмотр друзей определил разрешение с таким типом метки, то возможность получить такое же разрешение будет лишь у приложений, подписанных тем же ключом разработчика. В лекционной статье описывается пример с приложением FRIENDVIEW. Почему бы просто не пометить их небезопасными? Какой же смысл в этой штуке? Зачем нам третий тип Labels?

Студент: это облегчает разработчику управление своими приложениями?

Может быть, что у этого разработчика есть внутренние API, которые он хочет изолировать от воздействия сторонних программ, но при этом желает связать вместе свои собственные приложения для продуктивного взаимодействия. Профессор: да. Они могли бы иметь одно приложение, которое предварительно загружает контент с серверов Facebook, другое приложение смешивает этот контент, третье отслеживает ваше местоположение и при этом все эти компоненты взаимодействуют друг с другом. Гипотетически, создатели Facebook могли бы написать несколько приложений. Вот для такого случая они могли бы использовать подписанное разрешение.

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

Это описание того, что влёчет за собой данное разрешение. С метками также связано описание разрешений для пользователя. Именно это описание появляется, когда вам предлагается установить новое приложение.

Таким образом, среда выполнения Android будет просматривать все строки меток в манифесте приложения, которое вы собираетесь установить, и отображать пользователю описания всех этих помеченных строк, например: «вы собираетесь предоставить этому приложению привилегию набора номера, или разрешаете отправку СМС от вашего имени» и так далее.

Ведь эти метки — просто строки вольной формы. Интересный вопрос: что произойдёт, если вредоносное приложение изменит метку для какого-то другого приложения? Оно называется DIALPERM». Так что произойдёт, если вы – злонамеренное приложение, которое говорит: «о, у меня есть это новое, большое разрешение! Это опасно? Оно не имеет небезопасной метки, и его описание ничего не дает.

Студент: вероятно, оно не сможет затронуть структуру доменного имени приложения.

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

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

В лекционной статье описан случай, когда злоумышленник принуждает пользователя сначала установить вредоносное приложение, которое изменяет тип метки для приложения FRIENDVIEW на обычный тип со строкой описания типа «в этом вообще нет ничего интересного». Проблема в том, что если вы сначала установите вредоносное приложение, а затем некое важное приложение, то вредоносное приложение может потенциально исказить метки, используемые позже благонамеренным приложением. Позже, когда вы устанавливаете апплет FRIENDVIEW, он уже не может переопределить эту метку, потому что она уже определена, и теперь пользователь не сможет запретить другим приложениям использовать разрешение просмотра друзей.

Студент: возможно, система могла бы предупреждать о попытках изменить разрешение?

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

Студент: … и принадлежит другому приложению.

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

Он создаёт возможность получать и реагировать на сообщения других приложений, осуществляя что-то типа отправки сообщений между приложениями. Ещё одна интересная проблема Android связана с Broadcast receiver, или приёмником широковещательных сообщений. Широковещательные приемники используются для одного приложения, которое способно объявить некоторые события для любого другого приложения в системе. Сначала я должен описать, как эти сообщения взаимодействуют с приёмником.

Но о таких событиях, как загрузка системы или «Мои друзья поблизости», вы можете объявить каждому приложению, которого это касается. Как мы знаем, намерения обычно адресованы конкретному компоненту, например, просмотрщику изображений JPEG. Для этого и предназначены Broadcast receiver.

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

Во всяком случае, в начальной версии Android, когда вы отправляете широковещательное сообщение всем другим компонентам системы, эти приложения могут поддержать или не поддержать это сообщение. Мне кажется, что разработчики Android не совсем правильно реализовали эти вещи. Но большинство приложений всегда могут поддержать все широковещательные события в системе, и вы можете увидеть все, что происходит в телефоне, или все, что транслируется. Поэтому, если у вас есть приложение «Просмотр друзей», оно будет поддерживать эти сообщения, задействовав соответствующие компоненты, такие как Action или Date/MIME, в своём фильтре намерений Intent.

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

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

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

В лекционной статье приведён пример, когда вы заходите в приложение «Мои друзья поблизости» и получаете сообщение о том, что ваш друг находится рядом. Как же проверить подлинность того, откуда на самом деле приходит сообщение? Как вы можете себя в этом убедить? Откуда вы знаете, что это сообщение пришло от правильного компонента?

Разве вы не доверяете ядру системы? Студент: использованием кода ядра?

Сначала сообщение от App 1 обрабатывается монитором ссылок RM, который проверяет, откуда пришло данное сообщение, а затем направляет его App 2, приложению, которое должно его получить. Профессор: возможно, что так. Существует ли в Android способ в этом убедиться? Но как вам проверить, является ли это App 1 именно тем приложением, которое должно отправлять эти намерения?

Строго говоря, да, источник всегда аутентифицируется. Я думаю, что вы правы. Но что делать с именем источника? Вы точно знаете, какое приложение отправило сообщение. Как вы можете проверить, что именно этот источник может отправлять сообщения приложения «Мои друзья поблизости»?

Таким образом, один из способов сделать это — фактически наклеить метку на приемник широковещательных сообщений. Студент: возможно, метка описывает привилегии того, кто отправляет сообщения?
Профессор: да. Так вы можете сказать, что отправлять сообщения приёмнику разрешено только тем приложениям, которые имеют метку «Мои друзья поблизости».

Таким образом, один из способов отфильтровать тех, кто способен отправлять вам сообщения, является ограничение их полномочий с помощью метки Label. Если поместить такую метку в Broadcast receiver, вы будете знать, что к нему попадут только сообщения, отправленные приложениями с такой же меткой.

Android также предоставляет более конкретную функцию, которую вы можете использовать. Во многих случаях так и происходит. Вы можете запросить фреймворк по поводу того, является ли отправитель запрашиваемой вами функции обладателем метки с соответствующими разрешениями. Она называется «Проверка привилегий», и с её помощью вы можете проверить права отправителя. Таким образом, вы также можете судить о том, какие привилегии осуществляет отправитель конкретного сообщения в ситуациях, когда фреймворк не обеспечивает правильного использования механизмов манифеста.

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

Студент: можно ли предотвратить осуществление несанкционированных привилегий путём установки подписанных меток?

Профессор: думаю, да, подписанный тип меток способен это предотвратить.

Студент: требуется та же подпись, что и…

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

Студент: но ведь это взято из описания?

Профессор: совершенно верно.

Студент: а что произойдёт, если просто будет использовано другое описание?

В манифесте приложения есть две вещи. Профессор: я должен сказать, что это описание исходит от приложения, которое изначально определяет эту метку. Вторая вещь, которую вы моете сделать в манифесте — это определить новый тип метки. Вы можете запросить доступ к существующим меткам, то есть вы можете сказать, что это именно то приложение, от которого вам нужен доступ к разрешению на просмотр друзей. То есть кроме того, что вы можете сказать: «у меня есть приложение, и у него есть все нужные разрешения», вы также можете определить новый вид метки, то есть указать, что это небезопасная метка Dangerous и у неё есть соответствующее описание Description.

Но до тех пор, пока приложение, которое должно определить метку, устанавливается первым, у вас не возникнет проблем. Это то место, где у нас существует проблема: „кто пришёл первым, того и обслужили». Любое последующее приложение будет запрашивать метку только по имени строки, и тогда фреймворк Android будет извлекать описание и тип из того приложения, которое первым их определило.

Полезным свойством является то, что вы можете получить манифест, который в достаточной степени описывает свойства безопасности приложения. Я думаю, что дал вам некоторое представление о том, как работает Android. В нём вы можете прописать политику безопасности приложения обособленно от самого приложения, и эта политика будет осуществляться монитором ссылок независимо от того, что делает само приложение. Ещё одна вещь, которую придумали разработчики фреймворка «Андроид», называется «Обязательный контроль доступа».

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

Вы всё-таки можете написать код, который говорит о проверках безопасности, но было бы лучше, если бы вообще не было никаких проверок безопасности в коде, а все проверки осуществлялись бы в манифесте. Мы говорили об одном недостатке среды выполнения Android в отношении манифеста. Потенциально это небольшой компромисс, который использовали разработчики системы. Однако это может «подставить» такие вещи во фреймворке, как все RPC и так далее.

Удивительно, что фреймворк Android не слишком изменился с точки зрения безопасности с тех пор, как система была создана 5 или 6 лет назад. Я предполагаю, что достаточно трудно изменить файл манифеста после того, как вы разработали систему. Таким образом, в основном вы должны поддерживать обратную совместимость, потому что у вас нет возможности сделать всё заново. Потому что, как только приложение начинает использовать этот фреймворк, трудно сказать, что какое-то существующее приложение может «сломаться».

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

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

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

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

Вам нравятся наши статьи? Спасибо, что остаётесь с нами. Поддержите нас оформив заказ или порекомендовав знакомым, 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 не будет опубликован. Обязательные поля помечены *

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