- Linux exploits
- Типы эксплойтов
- Эксплойты
- Разбор эксплойтов
- Подготовительный этап
- Вызов уязвимого кода
- Полезная нагрузка
- Что в итоге?
- Администратор Linux. Базовый уровень
- Кому будет полезен курс?
- Почему стоит выбрать этот курс?
- Преподаватели
- Символы Unicode: о чём должен знать каждый разработчик
- Введение в кодировку
- Краткая история кодировки
- Проблемы с ASCII
- Что такое кодовые страницы ASCII?
- Безумие какое-то.
- Так появился Unicode
- Unicode Transform Protocol (UTF)
- Что такое UTF-8 и как она работает?
- Напоследок про UTF
- Это всё?
- Заключение
Linux exploits
Привет, хабровчане. В преддверии старта курса «Administrator Linux. Professional» наш эксперт — Александр Колесников подготовил интересную статью, которой мы с радостью делимся с вами.
Операционная система Linux доказала миру всю силу Open Source проектов — благодаря ей у нас сегодня есть возможность заглянуть в исходный код рабочей ОС и на его основе собрать свою собственную систему для решения тех или иных задач. По причине своей открытости Linux должна была стать самой безопасной операционной системой в мире, так как открытый исходный код позволяет развивать и улучшать подсистемы защиты от атак на ОС и совершенствовать саму операционную систему. Действительно, на данный момент существует большое количество созданных комьюнити защит: сегодня уже не так просто проэксплуатировать уязвимости типа переполнения буфера для получения повышенных привилегий так же, как 20 лет назад. Тем не менее, сегодня можно в открытом доступе встретить эксплойты, которые даже на последних версиях ядра могут повысить привилегии пользователя. Рассмотрим в этой статье, как это работает и почему так получается. Мы пройдемся по основным составляющим эксплойтов и рассмотрим, как работают некоторые из них.
Вся предоставленная информация была собрана исключительно в ознакомительных целях.
Типы эксплойтов
Выберем общий термин, которым будем обозначать, что есть эксплойт — алгоритм, который нарушает нормальное функционирование операционной системы, а именно — механизмы разграничения доступа. Также введем понятие уязвимости — это несовершенство программного обеспечения, которое может быть использовано алгоритмом эксплойта. Без уязвимости существование эксплойта невозможно.
Введем классификацию эксплойтов. Базовое разделение эксплойтов на подгруппы для любой операционной системы начинается на уровне архитектуры. Сегодня операционные системы включают в себя как минимум 2 уровня привилегий, которые используют для своей работы. Ниже приведен рисунок, который наглядно показывает разделение привилегий. Картинка взята отсюда.
Картинка очень наглядно показывает, что в операционной системе присутствует уровень Ядра (Kernel Space), обычно это самый привилегированный режим, именно здесь находится то, что мы называем операционной системой. И второй уровень — Пользовательский (User Space): здесь запускаются обычные приложения и сервисы, которые мы используем каждый день.
Исторически сложилось, что для каждого из перечисленных выше уровней могут быть найдены уязвимости, для которых может быть создан эксплойт, но эксплойты для каждого из уровней имеют свои ограничения.
На пользовательском уровне любой эксплойт, который затрагивает приложение, будет иметь ровно те привилегии, которые использовал пользователь, который запустил уязвимое приложение. Поэтому такой вид эксплойтов позволяет получить полное управление над ОС только в случае запуска приложения администратором системы. В противоположность пользовательскому уровню, уровень ядра, если содержит уязвимый код, может сразу дать возможность управлять операционной системой с максимальными привилегиями. Ниже сфокусируемся на исследовании этих эксплойтов.
Эксплойты
Представим небольшую статистику по раскрытию уязвимостей для ядра операционной системы Linux дистрибутивов Debian, SUSE, Ubuntu, Arch Linux последних 4-х лет.
Данные взяты отсюда. Картина не претендует на полноту, но показывает, что уязвимостей достаточно много, и даже сегодня есть из чего выбирать для построения эксплойта. Давайте попробуем описать, что из себя представляет эксплойт.
Любой эксплойт для любого уровня операционной системы сегодня состоит из частей, которые должны быть имплементированы в его коде:
1) Выставление необходимого отображения памяти
2) Создание необходимых объектов в ОС
3) Обход механизмов защиты ОС для используемой уязвимости
Вызов уязвимой части ПО.
Выполняет полезную нагрузку:
1) Для открытия доступа к ОС
2) Для изменения конфигурации ОС
3) Для вывода ОС из строя
При выполнении всех пунктов, которые указаны выше, можно написать работоспособный эксплойт. Возьмем для исследования несколько эксплойтов прошлых лет и попробуем выяснить, можно ли найти какие-то закономерности или заимствования, которые используются для нарушения разграничений доступа в операционной системе Linux. В качестве объектов исследования возьмем эксплойты, которые используют следующие уязвимости с CVE идентификаторами:
Разбор эксплойтов
CVE-2020-8835 распространяется на ядро ОС Linux от версии 5.5.0. Уязвимость находится в имплементации технологии ebpf . Технология была разработана для того, чтобы пользователь мог создавать кастомные обработчики для фильтрации сетевого трафика. В качестве основной составляющей для выполнения фильтрации используется виртуальная машина с собственным набором команд. Код, который выполняется виртуальной машиной, живет в ядре: ошибка в этом коде приносит атакующему возможность работать с памятью с максимальными привилегиями. В случае описываемой уязвимости проблема заключалась в том, что операции обработки команд длины 32 бита недостаточно корректно обрабатывались, и виртуальная машина могла писать и читать данные в оперативной памяти ядра.
Как автор эксплойта использует данную уязвимость и какая выполняется полезная нагрузка, рассмотрим дальше.
Подготовительный этап
За этот этап отвечает следующая часть кода.
Строка 394 — создание объекта в памяти, который будет хранить данные о командах для ebpf . Строка 400 загружает в память код, который будет выполняться в виртуальной машине и позволит нарушить условия обработки 32 битных команд. Подготовка памяти окончена, следующие строки будут создавать объект сокета, который обеспечит вызов загруженных команд для bpf . После этого начнется этап вызова уязвимости.
Вызов уязвимого кода
Вызов уязвимого кода, а точнее — работа с командами виртуальной машины, осуществляется со строки 423 по 441. Основная задача этого кода — получить базовый адрес структуры, которая находится в памяти, в данном случае это куча (heap) процесса. Как только эти команды выполнятся, эксплойт сможет обнаружить в памяти данные, используемые операционной системой для контроля разграничения доступа. В операционной системе Linux эти данные хранятся в структуре taskstruct .
Полезная нагрузка
Полезная нагрузка данного эксплойта заключается в том, что после его выполнения можно запустить процесс с правами пользователя root . Для этого код эксплойта производит модификацию полей структуры ядра операционной системы Linux — cred это структура, которая входит в структуру taskstruct . Исходный код структуры cred можно найти здесь.
Действия по модификации полей struct cred можно увидеть на строках 472,473,474 . То есть этим действием обнуляется значение uid, gid, sgid создаваемого процесса. С точки зрения ОС это установка значений идентификаторов, которые обычно использует root . Метод очень похож на тот, который применяется для атак на операционную систему Windows.
Обезопасить себя без обновления ОС можно, если внести следующие изменения в конфиг: sudo sysctl kernel.unprivileged_bpf_disabled=1
CVE-2020-27194 — снова уязвимость в ebpf . Существует для ядра версий 5.8.*. Создатели этой технологии шутят, что bpf — это JavaScript для ядра. На самом деле это суждение не далеко от истины. Виртуальная машина действительно проводит манипуляции над командами с помощью технологии JIT, что само собой несет все типичные уязвимости браузеров в ядро операционной системы, то есть сложно настроить подсистемы защиты для того чтобы обезопасить выполнение кода. Рассматриваемая уязвимость заключается в том, что из кода виртуальной машины можно провести модификацию любой области оперативной памяти. Возможно это из-за того, что виртуальная машина небезопасно работает с операциями 64 битной длины. Полностью аналогичная уязвимость той, которую мы рассматривали выше.
Эксплойт, который создан для того, чтобы использовать описанную уязвимость, выполняет те же операции, что и эксплойт CVE-2020-8835. Алгоритм эксплойта следующий:
Загрузить код с обработкой 64 битных операций в память
Создать сокет и отправить данные для вызова команд ebpf
Найти в памяти адрес структуры taskstruct за счет выполнения команд в виртуальной машине
Модифицировать значения uid,gid,sgid и запустить интерактивную оболочку.
Автор писал исходный код с новыми фишками и дополнительными функциями. Предлагаем читателю самостоятельно взглянуть на код. Перечисленные этапы работы эксплойта выше не дадут запутаться.
Защита от этой уязвимости без использования обновления такая же: sudo sysctl kernel.unprivileged_bpf_disabled=1
Что в итоге?
На основании двух эксплойтов, который были рассмотрены в статье, можно предположить, что повышение привилегий в современной ОС Linux — это больше не темная магия программирования, а вполне отлаженный шаблонный процесс, который включает в себя переиспользование функций и объектов в оперативной памяти. При этом даже не нужно писать базонезависимый (shellcode) код, который будет выполнять большую часть действий. Достаточно просто изменить идентификаторы, которые используются для назначения привилегий для пользователей.
Источник
Администратор Linux. Базовый уровень
Стенды для отработки материалов предоставляются партнером курса AdvancedHosting
На курсе вы получите навыки администрирования Linux, которые выделят вас среди начинающих администраторов:
- Познакомитесь с базовыми понятиями ОС Linux
- Изучите команды для работы в Bash
- Научитесь настраивать WEB-сервера (apache, nginx) и MySQL-сервер
- Узнаете, как использовать инструменты в работе системного администратора: контейнеры Docker и система контроля версии Git
- Рассмотрите базовые понятия анализа сетевого траффика и правил фильтрации
- Рассмотрите системы мониторинга (zabbix, icinga, cacti, grafana, prometheus)
- Обсудите логирование информации
Вы рассмотрите следующий стек технологий: Linux, Zabbix, Prometheus, TCP/IP, Nginx, Apache, MySQL, Bash, Docker, Git, NoSQL, Grafana, ELK.
К концу обучения вы соберете портфолио из выполненных работ и сделаете итоговый проект на основе знаний, полученных на курсе.
Вы сможете опубликовать проект и показывать его на собеседованиях.
На протяжении всего курса вас будет вести персональный ментор.
Кому будет полезен курс?
- Начинающим системным администраторам Linux;
- Системным администраторам Windows
- Разработчикам
- Специалистам по тестированию
- Всем, кто интересуются темой администрирования и хочет войти в новую для себя специальность
Почему стоит выбрать этот курс?
Курс включает в себя четыре логических блока:
1. Работа непосредственно с Linux ( структура Linux, основные команды, работа с файлами и ПО).
2. Настройка веб-сервера, базы данных (mysql и nosql) и работа с сетью.
3. Мониторинг и логирование на базе Zabbix , Prometheus , Grafana и ELK.
4. Дополнительные важные уроки для работы в команде — Git и Docker.
В начале курса базовые команды вы изучите в формате видеозаписи в виде коротких роликов не более 10 минут.
Далее настройку сервера и более сложные темы вы будете проходить в формате практических живых вебинаров.
Итогом курса станет ваш личный проект.
ПЕРСОНАЛЬНЫЙ МЕНТОР: онлайн-сессии на 40 минут каждую неделю.
- В начале обучения за вами закрепляется ментор. Как и преподаватели, менторы — эксперты, работающие администраторами Linux.
- Раз в неделю вы делаете домашнее задание.
- На сессии ментор прокомментирует ваше решение.
Преподаватели
Специалист по UNIX-системам в компании Mail.Ru Group.
Работает с операционной системой Linux более 7 лет.
Параллельно с основной деятельностью очень любит преподавать основы Linux начинающим специалистам и делает это успешно более 5 лет.
Входит в топ-3 лучших преподавателей образовательных порталов.
Специалист по компьютерным сетям и linux-системам.
Системный администратор в Mail.Ru Group.
Начинал свой карьерный путь с младшего администратора в аутсорсинговой компании.
Интересуется Linux и любит делится своим опытом с начинающими специалистами. Активно занимается преподавательской деятельностью на различных образовательных площадках.
Получил высшее образование по специальности «Информационные системы в экономике» в РЭУ им. Г.В. Плеханова.
Закончил аспирантуру и защитил диссертацию, кандидат экономических наук.
Параллельно с веб-разработкой преподавал интернет-технологии в РЭУ им. Г. В. Плеханова.
В веб-разработке я более 15 лет.
За это время под моим руководством и с моим участием было разработано более 100 веб-сайтов и приложений, система управления сайтами и другие системы на веб-технологиях.
Имею опыт преподавания в ВУЗе более 10 лет и более 3 лет на онлайн-платформах.
Сейчас я технический директор «Метод Лаб».
Занимаюсь техническим руководством и оптимизацией клиентской и серверной производительности веб-приложений, автор YouTube-каналов «Ускорение сайтов» и «Поддержка сайтов». Оптимизация производительности требует широких знаний в смежных областях (фронтэнд, бекэнд, базы данных, администирирование, сети и т.д.), что придаёт этой задаче особый интерес.
Руководитель программы охоты на уязвимости Mail.Ru Group.
Один из руководителей группы VolgaCTF.
Организатор множества всероссийских и международных соревнований в формате CTF.
Более 10 лет занимается обучением специалистов по информационной безопасности.
Имеет авторские программы по экстремальному обучению.
Администратор Linux систем. Последние несколько лет работает в аутсорсинговой компании и занимается настройкой, сопровождением Linux систем под нужды заказчика.
Источник
Символы Unicode: о чём должен знать каждый разработчик
Если вы пишете международное приложение, использующее несколько языков, то вам нужно кое-что знать о кодировке. Она отвечает за то, как текст отображается на экране. Я вкратце расскажу об истории кодировки и о её стандартизации, а затем мы поговорим о её использовании. Затронем немного и теорию информатики.
Введение в кодировку
Компьютеры понимают лишь двоичные числа — нули и единицы, это их язык. Больше ничего. Одно число называется байтом, каждый байт состоит из восьми битов. То есть восемь нулей и единиц составляют один байт. Внутри компьютеров всё сводится к двоичности — языки программирования, движений мыши, нажатия клавиш и все слова на экране. Но если статья, которую вы читаете, раньше была набором нулей и единиц, то как двоичные числа превратились в текст? Давайте разберёмся.
Краткая история кодировки
На заре своего развития интернет был исключительно англоязычным. Его авторам и пользователям не нужно было заботиться о символах других языков, и все нужды полностью покрывала кодировка American Standard Code for Information Interchange (ASCII).
ASCII — это таблица сопоставления бинарных обозначений знакам алфавита. Когда компьютер получает такую запись:
то с помощью ASCII он преобразует её во фразу «Hello world».
Один байт (восемь бит) был достаточно велик, чтобы вместить в себя любую англоязычную букву, как и управляющие символы, часть из которых использовалась телепринтерами, так что в те годы они были полезны (сегодня уже не особо). К управляющим символам относился, например 7 (0111 в двоичном представлении), который заставлял компьютер издавать сигнал; 8 (1000 в двоичном представлении) — выводил последний напечатанный символ; или 12 (1100 в двоичном представлении) — стирал весь написанный на видеотерминале текст.
В те времена компьютеры считали 8 бит за один байт (так было не всегда), так что проблем не возникало. Мы могли хранить все управляющие символы, все числа и англоязычные буквы, и даже ещё оставалось место, поскольку один байт может кодировать 255 символов, а для ASCII нужно только 127. То есть неиспользованными оставалось ещё 128 позиций в кодировке.
Вот как выглядит таблица ASCII. Двоичными числами кодируются все строчные и прописные буквы от A до Z и числа от 0 до 9. Первые 32 позиции отведены для непечатаемых управляющих символов.
Проблемы с ASCII
Позиции со 128 по 255 были пустыми. Общественность задумалась, чем их заполнить. Но у всех были разные идеи. Американский национальный институт стандартов (American National Standards Institute, ANSI) формулирует стандарты для разных отраслей. Там утвердили позиции ASCII с 0 по 127. Их никто не оспаривал. Проблема была с остальными позициями.
Вот чем были заполнены позиции 128-255 в первых компьютерах IBM:
Какие-то загогулины, фоновые иконки, математические операторы и символы с диакретическим знаком вроде é. Но разработчики других компьютерных архитектур не поддержали инициативу. Всем хотелось внедрить свою собственную кодировку во второй половине ASCII.
Все эти различные концовки назвали кодовыми страницами.
Что такое кодовые страницы ASCII?
Здесь собрана коллекция из более чем 465 разных кодовых страниц! Существовали разные страницы даже в рамках какого-то одного языка, например, для греческого и китайского. Как можно было стандартизировать этот бардак? Или хотя бы заставить его работать между разными языками? Или между разными кодовыми страницами для одного языка? В языках, отличающихся от английского? У китайцев больше 100 000 иероглифов. ASCII даже не может всех их вместить, даже если бы решили отдать все пустые позиции под китайские символы.
Эта проблема даже получила название Mojibake (бнопня, кракозябры). Так говорят про искажённый текст, который получается при использовании некорректной кодировки. В переводе с японского mojibake означает «преобразование символов».
Пример бнопни (кракозябров).
Безумие какое-то.
Именно! Не было ни единого шанса надёжно преобразовывать данные. Интернет — это лишь монструозное соединение компьютеров по всему миру. Представьте, что все страны решили использовать собственные стандарты. Например, греческие компьютеры принимают только греческий язык, а английские отправляют только английский. Это как кричать в пустой пещере, тебя никто не услышит.
ASCII уже не удовлетворял жизненным требованиям. Для всемирного интернета нужно было создать что-то другое, либо пришлось бы иметь дело с сотнями кодовых страниц.
��� Если только ������ вы не хотели ��� бы ��� читать подобные параграфы. �֎֏0590��׀ׁׂ׃ׅׄ׆ׇ
Так появился Unicode
Unicode расшифровывают как Universal Coded Character Set (UCS), и у него есть официальное обозначение ISO/IEC 10646. Но обычно все используют название Unicode.
Этот стандарт помог решить проблемы, возникавшие из-за кодировки и кодовых страниц. Он содержит множество кодовых пунктов (кодовых точек), присвоенных символам из языков и культур со всего мира. То есть Unicode — это набор символов. С его помощью можно сопоставить некую абстракцию с буквой, на которую мы хотим ссылаться. И так сделано для каждого символа, даже египетских иероглифов.
Кто-то проделал огромную работу, сопоставляя каждый символ во всех языках с уникальными кодами. Вот как это выглядит:
Префикс U+ говорит о том, что это стандарт Unicode, а число — это результат преобразования двоичных чисел. Стандарт использует шестнадцатеричную нотацию, которая является упрощённым представлением двоичных чисел. Здесь вы можете ввести в поле что угодно и посмотреть, как это будет преобразовано в Unicode. А здесь можно полюбоваться на все 143 859 кодовых пунктов.
Уточню на всякий случай: речь идёт о большом словаре кодовых пунктов, присвоенных всевозможным символам. Это очень большой набор символов, не более того.
Осталось добавить последний ингредиент.
Unicode Transform Protocol (UTF)
UTF — протокол кодирования кодовых пунктов в Unicode. Он прописан в стандарте и позволяет кодировать любой кодовый пункт. Однако существуют разные типы UTF. Они различаются количеством байтов, используемых для кодировки одного пункта. В UTF-8 используется один байт на пункт, в UTF-16 — два байта, в UTF-32 — четыре байта.
Но если у нас есть три разные кодировки, то как узнать, какая из них применяется в конкретном файле? Для этого используют маркер последовательности байтов (Byte Order Mark, BOM), который ещё называют сигнатурой кодировки (Encoding Signature). BOM — это двухбайтный маркер в начале файл, который говорит о том, какая именно кодировка тут применена.
В интернете чаще всего используют UTF-8, она также прописана как предпочтительная в стандарте HTML5, так что уделю ей больше всего внимания.
Этот график построен в 2012-м, UTF-8 становилась доминирующей кодировкой. И всё ещё ею является.
Что такое UTF-8 и как она работает?
UTF-8 кодирует с помощью одного байта каждый кодовый пункт Unicode с 0 по 127 (как в ASCII). То есть если вы писали программу с использованием ASCII, а ваши пользователи применяют UTF-8, они не заметят ничего необычного. Всё будет работать как задумано. Обратите внимание, как это важно. Нам нужно было сохранить обратную совместимость с ASCII в ходе массового внедрения UTF-8. И эта кодировка ничего не ломает.
Как следует из названия, кодовый пункт состоит из 8 битов (один байт). В Unicode есть символы, которые занимают несколько байтов (вплоть до 6). Это называют переменной длиной. В разных языках удельное количество байтов разное. В английском — 1, европейские языки (с латинским алфавитом), иврит и арабский представлены с помощью двух байтов на кодовый пункт. Для китайского, японского, корейского и других азиатских языков используют по три байта.
Если нужно, чтобы символ занимал больше одного байта, то применяется битовая комбинация, обозначающая переход — он говорит о том, что символ продолжается в нескольких следующих байтах.
И теперь мы, как по волшебству, пришли к соглашению, как закодировать шумерскую клинопись (Хабр её не отображает), а также значки emoji!
Подытожив сказанное: сначала читаем BOM, чтобы определить версию кодировки, затем преобразуем файл в кодовые пункты Unicode, а потом выводим на экран символы из набора Unicode.
Напоследок про UTF
Коды являются ключами. Если я отправлю ошибочную кодировку, вы не сможете ничего прочесть. Не забывайте об этом при отправке и получении данных. В наших повседневных инструментах это часто абстрагировано, но нам, программистам, важно понимать, что происходит под капотом.
Как нам задавать кодировку? Поскольку HTML пишется на английском, и почти все кодировки прекрасно работают с английским, мы можем указать кодировку в начале раздела .
Важно сделать это в самом начале , поскольку парсинг HTML может начаться заново, если в данный момент используется неправильная кодировка. Также узнать версию кодировки можно из заголовка Content-Type HTTP-запроса/ответа.
Если HTML-документ не содержит упоминания кодировки, спецификация HTML5 предлагает такое интересное решение, как BOM-сниффинг. С его помощью мы по маркеру порядка байтов (BOM) можем определить используемую кодировку.
Это всё?
Unicode ещё не завершён. Как и в случае с любым стандартом, мы что-то добавляем, убираем, предлагаем новое. Никакие спецификации нельзя назвать «завершёнными». Обычно в год бывает 1-2 релиза, найти их описание можно здесь.
Если вы дочитали до конца, то вы молодцы. Предлагаю сделать домашнюю работу. Посмотрите, как могут ломаться сайты при использовании неправильной кодировки. Я воспользовался этим расширением для Google Chrome, поменял кодировку и попытался открывать разные страницы. Информация была совершенно нечитаемой. Попробуйте сами, как выглядит бнопня. Это поможет понять, насколько важна кодировка.
Заключение
При написании этой статьи я узнал о Майкле Эверсоне. С 1993 года он предложил больше 200 изменений в Unicode, добавил в стандарт тысячи символов. По состоянию на 2003 год он считался самым продуктивным участником. Он один очень сильно повлиял на облик Unicode. Майкл — один из тех, кто сделал интернет таким, каким мы его сегодня знаем. Очень впечатляет.
Надеюсь, мне удалось показать вам, для чего нужны кодировки, какие проблемы они решают, и что происходит при их сбоях.
Источник