open atlas
↑ К треку
Наступательная безопасность RED · 03 · 02

Privilege escalation

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

RED Middle ◷ 15 min
Уровень
ОсновыJuniorMiddleSenior

На авторизованном тесте плацдарм невзрачен: деплой-скрипт слил пароль сервисной учётки, и теперь есть шелл, работающий как www-data на Linux-машине. Эта учётка может читать веб-корень и почти ничего больше — не трогает /etc/shadow, не читает данные других арендаторов, не ставит постоянный бэкдор. Джуниор-тестировщик останавливается здесь и пишет «низкая критичность, ограниченная учётка». Зрелый инженер идёт дальше, потому что плацдарм редко там, где ценность. За десять минут перечисление выдаёт список: бэкап-скрипт, принадлежащий root, доступен на запись всем и запускается из cron каждые пять минут; кастомный бинарь имеет выставленный бит SUID и вызывает tar без абсолютного пути; sudo настроен так, что www-data может запустить один «безобидный» админ-инструмент, который как раз порождает подоболочку. Ни одно из этого не эксплойт. Каждое — конфигурация, которую хост поставил именно так. Атакующий не вламывается снова — он поднимается по лестнице, которую система построила для него, и выходит как root.

К концу урока ты сможешь объяснить, как атакующий перечисляет локальный путь эскалации на Linux и Windows, почему каждая ступень — это просчёт конфигурации, а не «взлом», и рефлекс защитника, который убирает ступень до того, как по ней поднимутся.

Сначала авторизация: это вскрытие со стороны защитника

Всё ниже предполагает подписанную работу с явным scope — намеренно уязвимую лабораторию, CTF-машину, машину, которой ты владеешь, или систему, названную в bug-bounty-программе. Запуск инструментов перечисления против хоста, на который у тебя нет авторизации, или переход с низкой учётки на root на чужой инфраструктуре — это несанкционированный доступ почти в любой юрисдикции, без оговорок. Мы изучаем перечисление атакующего ровно по одной причине: нельзя надёжно закрыть путь эскалации, который понимаешь только как пункт чек-листа. Читай это как вскрытие, которое защитник проводит над собственным хостом, — учась видеть бит SUID и правило sudo так, как их видит атакующий, чтобы ступени не было в дизайне ещё до того, как её найдёт любой тестировщик. Никаких боевых payload’ов здесь, только механизм, который подсказывает, какую ступень убрать.

Форма атаки: плацдарм, перечислить, злоупотребить, закрепиться

Повышение привилегий — не единичный эксплойт, это фаза. У атакующего уже есть выполнение кода как некоего низкопривилегированного принципала — веб-пользователя вроде www-data или IIS APPPOOL, скомпрометированной сервисной учётки, CI-раннера. Цель — вертикальное движение: от этого принципала к более высокому (root, SYSTEM, Administrator, доменный админ), что открывает чтение любого файла, установку персистентности и переход к другим хостам. Цикл всегда один и тот же: перечислить локальное окружение на предмет всего неправильно настроенного, найти примитив, пересекающий границу доверия, злоупотребить им, чтобы выполнить код как более высокий принципал, затем закрепиться, чтобы плацдарм пережил перезагрузку или сброс пароля.

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

Linux: четыре повторяющиеся ступени

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

SUID/SGID-бинари. Файл с битом SUID выполняется как его владелец независимо от того, кто его запустил, — так SUID-root-бинарь выполняется как root, даже когда его запускает www-data. Это сделано намеренно для инструментов вроде passwd, которым нужен привилегированный момент. Опасность — SUID-бинарь, который делает то, чего не должен: вызывает помощника по относительному имени (так атакующий добавляет вредоносный каталог в начало PATH), читает или пишет файл, который называет вызывающий, или является интерпретером общего назначения, которому вообще нельзя быть SUID. SUID-root-программа, вызывающая system("tar ..."), отдаёт атакующему root в момент, когда он кладёт поддельный tar раньше в PATH. Фикс — это минимальная привилегия на бинаре: снять бит SUID, если он не нужен по-настоящему, а если нужен — бинарь должен использовать абсолютные пути, очищать окружение и не выставлять ни одного файла или команды, которыми может управлять вызывающий.

Просчёт sudo. sudo предназначен давать узкое повышение, но небрежный /etc/sudoers даёт широкое. Разрешить низкой учётке запускать редактор, пейджер или скриптовый интерпретер как root — фактически выдать root-шелл, потому что эти программы умеют порождать подоболочки или читать произвольные файлы. NOPASSWD на бинаре с shell-escape — классический подарок. Рефлекс защитника: каждое правило sudo — это исключение из deny-by-default, поэтому проверяй каждое вопросом «может ли именно эта команда в этой конфигурации быть превращена в выполнение произвольного кода?» — и если да, это замаскированная выдача root.

Записываемые привилегированные задания и сервисы. Задание cron, юнит systemd или скрипт сервиса, который работает как root, но лежит в файле, доступном на запись всем (или вызывает скрипт в каталоге, доступном на запись всем), позволяет любому пользователю переписать то, что root выполнит следующим. Просчёт — это права на файл, а не планировщик. Фикс — заблокировать владение и права на всё, чего касается привилегированный планировщик, чтобы низкая учётка никогда не могла отредактировать следующее, что запустит root.

Эксплойты ядра и устаревших компонентов. Когда конфигурация чистая, атакующий откатывается к известной уязвимости в ядре или привилегированном демоне — CVE в setuid-помощнике, баг ядра, дающий локальному пользователю root. Эту ступень закрывают не правами, а патчингом: непропатченное ядро с истёкшим сроком поддержки — это постоянный примитив локального root для любого, у кого уже есть шелл. Эксплойты ядра шумнее и могут уронить машину, поэтому осторожный атакующий пробует их последними — что и сигнализирует о хосте, отставшем с обновлениями.

СтупеньЧто перечисляет атакующийПочему пересекает границуФикс защитника
SUID / SGID-бинарьФайлы с выставленным битом setuidРаботает как владелец (root), но доверяет PATH/аргументам вызывающегоСнять бит; абсолютные пути; чистое окружение
Правило sudoЧто эта учётка может запускать как rootПрограмма с shell-escape = root-шеллУзкие правила; никаких сбегающих бинарей
Записываемый cron / сервисПрава на скрипты, запускаемые rootНизкий пользователь переписывает то, что запустит rootЗаблокировать владение и права на путь
Ядро / устаревший демонВерсия ядра, EOL-компонентыИзвестный local-root CVE в привилегированном кодеПатчить; выводить ядра с истёкшим сроком
Windows: некавыченный путьПути бинарей сервисов с пробеламиСервис SYSTEM запускает файл атакующего первымЗакавычить пути; запереть каталог установки
Windows: токен / DLLПривилегии, слабые ACL сервисов, пути DLLЗлоупотребление токеном или подсунутая DLL работает как SYSTEMМин. привилегия; жёсткие ACL; подписанные DLL

Windows: тот же зазор, другие имена

Эскалация на Windows рифмуется с Linux — тот же зазор «работает высоко, доверяет низкому» — под другими механизмами. Некавыченные пути сервисов — хрестоматийный пример: сервис, зарегистрированный как C:\Program Files\My App\svc.exe без кавычек и работающий как SYSTEM, заставляет Windows сначала пробовать C:\Program.exe; если низкий пользователь может писать в C:\, его бинарь выполняется как SYSTEM. Слабые права сервиса позволяют низкому пользователю переконфигурировать бинарь, который запускает сервис SYSTEM. DLL hijacking подсовывает вредоносную библиотеку туда, откуда привилегированный процесс загружает её по небезопасному порядку поиска. Подмена токена злоупотребляет некоторыми привилегиями (у части сервисных учёток), чтобы выдать себя за токен SYSTEM. AlwaysInstallElevated — политика, запускающая MSI-инсталляторы как SYSTEM, — превращает любой пользовательский инсталлятор в выдачу root. Другая поверхность, идентичная корневая причина: высокопривилегированный компонент доверяет пути, праву или токену, на который может влиять низкопривилегированный пользователь.

Почему это работает

Почему атакующие пробуют примитив на чистой конфигурации (SUID, sudo, записываемый cron) раньше эксплойта ядра, когда баг ядра — более мощный инструмент? Две причины, обе операционные. Первая — надёжность: просчёт конфигурации детерминирован — злоупотреби SUID-бинарём и получишь root каждый раз, — тогда как эксплойт ядра может не сработать против неожиданного уровня патчей и, хуже того, уронить машину в панику, завершив работу и подсветив мониторинг. Вторая — скрытность: подъём по конфигурации, которую хост поставил, выглядит как обычное использование обычных инструментов, тогда как загрузка эксплойта ядра громка и обнаружима. Вывод защитника — зеркальный: чистая конфигурация с минимальными привилегиями убирает тихие ступени, которые атакующий предпочитает, вынуждая его на шумный путь ядра, где твой патчинг и твоё обнаружение реально получают шанс победить.

Как защитник убирает лестницу

Объединяющая защита — это минимальная привилегия на каждом слое, потому что каждая ступень — это место, где привилегия была выдана шире, чем требовала задача. Считай, что плацдарм случится — фишинг, слитая учётка, баг приложения — и проектируй так, чтобы плацдарм был тупиком. Проверь инвентарь SUID/SGID и сними бит со всего, что его не заслуживает; считай каждое правило sudo явным исключением и отвергай любую программу с shell-escape; заблокируй владение и права на каждом файле, которого касается привилегированный планировщик или сервис; держи ядра и привилегированные демоны пропатченными, чтобы не было постоянного local-root CVE; на Windows закавычивай пути сервисов, ужесточай ACL сервисов и отключай AlwaysInstallElevated. Затем добавь обнаружение самого подъёма — алерт на новые SUID-файлы, на правки привилегированных юнитов, на порождение шелла сервисной учёткой — чтобы даже пропущенная тобой ступень была поймана. Зрелый рефлекс во всём этом тот же, что и всюду в безопасности: запрещай по умолчанию, выдавай минимум и считай, что нижняя граница будет пробита.

Выбери лучший вариант

На авторизованном тесте SUID-root-бинарь вызывает `tar` по относительному имени, а низкая учётка управляет `PATH`. Выбери фикс, который реально закрывает эскалацию.

Викторина

Сервис Windows работает как SYSTEM с путём бинаря `C:\Program Files\My App\svc.exe`, зарегистрированным без кавычек, и низкий пользователь может писать в `C:\`. Каков класс и точный фикс?

Викторина

Почему осторожный атакующий пробует эскалацию через просчёт конфигурации (SUID, sudo, записываемый cron) раньше, чем берётся за эксплойт ядра?

Расставь шаги по порядку

Упорядочь фазы атаки локального повышения привилегий, от стартового плацдарма до устойчивого удержания хоста:

  1. 1 У атакующего есть выполнение кода как низкопривилегированной учётки (напр. www-data)
  2. 2 Перечислить хост на просчёты конфигурации (SUID, sudo, записываемые задания, версия ядра)
  3. 3 Найти компонент, который работает привилегированно, но доверяет низкопривилегированному входу
  4. 4 Злоупотребить этим входом, чтобы выполнить код как root / SYSTEM
  5. 5 Закрепиться, чтобы повышенный доступ пережил перезагрузку или сброс
Вспомните перед уходом
  1. 01
    Объясни ментальную модель локального повышения привилегий и почему каждая ступень — это просчёт конфигурации, а не «взлом».
  2. 02
    Назови повторяющиеся ступени эскалации на Linux и Windows и единый защитный принцип, который их закрывает, и объясни, почему атакующие предпочитают просчёт конфигурации эксплойтам ядра.
Итог

Локальное повышение привилегий — это фаза, а не единичный эксплойт: атакующий с низкопривилегированным плацдармом (www-data, сервисная учётка) перечисляет хост в поисках компонента, который работает с высокой привилегией, но доверяет входу, которым управляет низкий пользователь, злоупотребляет этим зазором, чтобы выполнить код как root или SYSTEM, и затем закрепляется. Каждая ступень — это просчёт конфигурации, который хост уже поставил, а не магический взлом: на Linux — SUID-бинарь, доверяющий относительному пути или PATH вызывающего, правило sudo для программы с shell-escape, доступный на запись всем файл cron или сервиса, или старое ядро с известным local-root CVE; на Windows — некавыченный путь сервиса, слабые ACL сервисов, DLL hijacking, подмена токена или AlwaysInstallElevated. У всех одна форма — высокая привилегия, доверяющая низкопривилегированному входу, — и один фикс: минимальная привилегия на каждом слое, чтобы плацдарм был тупиком, плюс патчинг, чтобы убрать постоянные CVE ядра, и обнаружение, чтобы поймать пропущенный тобой подъём. Атакующие берутся за просчёты конфигурации раньше эксплойтов ядра, потому что те детерминированы и тихи, — именно поэтому чистая конфигурация убирает предпочитаемые ими ступени. Теперь, читая привилегированный бинарь, правило sudo, задание cron или определение сервиса, твой первый вопрос: работает ли это с большей привилегией, чем нужно задаче, и может ли низкая учётка влиять на то, что оно делает?

Практика

Начни сверху. Задачи идут от простого к сложному: вспомнить факт, применить к случаю, затем senior-уровень. Открой, попробуй, потом открой ответ.

вспомнитьприменитьуглубить0 из 6 завершено
Связанные уроки

Что-то непонятно?

Задай вопрос по этому уроку. Вопросы анонимны и попадают напрямую автору — урок станет лучше.

хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources2
expand
  1. 01
  2. 02

Trademarks belong to their respective owners. Editorial reference only.