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

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

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

Давайте рассмотрим гипотетическую ситуацию: мы получили права на уровне пользователя домена в среде с сотнями тысяч рабочих станций и серверов, присоединенных к лесу активного каталога с несколькими доменами с различными степенями ограничений. Наша цель — увеличить права до «Enterprise Admin», если это возможно. К счастью, топология сети фактически плоская; тем не менее, клиент применяет крайне строгие методы наименьших прав и сеть не имеет «лёгких» уязвимостей. (т. е. мы не отделаемся быстрым перебором). После борьбы с поиском средств для повышения прав, мы, наконец, смогли скомпрометировать учетную запись администратора сервера, которую мы назовём «Steve-Admin».

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

Далее я расскажу и продемонстрирую, как автоматизировать этот процесс.

Предварительная работа

Данный метод использует существующие инструменты и алгоритмы, любезно опубликованные некоторыми очень умными и трудолюбивыми ребятами:

Теория графов

Представьте себе, что вы хотите найти путь из Сиэтла, штат Вашингтон в Портленд, штат Орегон. Вы можете посмотреть на карту и довольно легко определить, что маршрут Interstate-5 проведет вас туда. Компьютер может найти путь между Сиэтлом и Портлендом (и между «Steve-Admin» и «Enterprise Admin», если таковой существует) с помощью математики.

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

  • Вершина — точка, используется для обозначения отдельного элемента в системе. Например, города на карте являются вершинами.
  • Ребро — линия, соединяющая вершины. Рёбра могут быть направленными и не направленными. Если Сиэтл и Портленд рассмотреть как вершины, то Interstate-5 можно рассматривать как ребро, соединяющее эти города.
  • Путь — набор узлов, соединённых рёбрами от одного узла к другому.
  • Смежности — отношение вершин и рёбер. Вершины, которые соединены ребром, называются смежными.

Дизайн графов

Сопоставим нашей компьютерной среде модель графа следующим образом:

Screen-Shot-2016-02-06-at-3.46.00-PM-288x300

  • Каждый пользователь и компьютер является вершиной.
  • Все рёбра ориентированны (направлены).
  • Направленное ребро от пользователя к компьютеру указывает права локального администратора.
  • Направленное ребро от компьютера к пользователю указывает на авторизованного пользователя.

Представьте себе простую сеть, состоящую из двух компьютеров и двух пользователей. Учетная запись «Administrator» обладает правами администратора на обеих системах. На одной из систем зарегистрирован пользователь «mnelson». Тогда визуальное представление этой системы будет выглядеть следующим образом:

Каждый пользователь и компьютер является вершиной. Оранжевые рёбра говорят о том, что учетная запись «Administrator» имеет права администратора на обеих системах. Синее ребро означает, что «mnelson» авторизовался на HR-WS-002. В этой конструкции, ребро всегда означает, что вершина, из которой выходит ребро, может поставить под угрозу вершину, в которую ребро входит: «Administrator» может поставить под угрозу HR-WS-002, и HR-WS-002 (т. е. системная учетная запись на этой машине) может поставить под угрозу пользователя «mnelson».

Построение графа

Берем каждого пользователя и компьютер в качестве вершины. Используем две команды в PowerView — Get-NETUSER и Get-NetComputer:

Screen-Shot-2016-02-14-at-10.46.31-PM-1-768x101

Визуальное представление графа на данной стадии может выглядеть следующим образом:

Screen-Shot-2016-02-07-at-9.32.23-PM-705x397

В рамках подготовки к использованию алгоритма Дейкстры, мы даем каждой вершине следующие свойства:

  • Имя Имя вершины. Пример: ‘mnelson’ или ‘HR-WS-002’
  • Рёбра Массив смежных вершин. По умолчанию — значение $Null.
  • Расстояние — количество переходов (прыжков), необходимых для попадания в эту вершину. Изначально установлена бесконечность.
  • Посещения было ли определено самое короткое расстояние до этого узла. Изначально установлено значение $False.
  • Предшественник название предыдущей вершины в пути от источника вершины до этой вершины. Изначально установлено значение $Null.

Screen-Shot-2016-02-14-at-10.48.05-PM-1024x278

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

Screen-Shot-2016-02-14-at-10.51.55-PM-768x382

В тестовой лаборатории заполненный граф может быть визуально представлен следующим образом:

Screen-Shot-2016-02-06-at-5.48.56-PM-768x476

Напомним , что пользователь->компьютер обозначает права администратора, а компьютер->пользователь обозначает вошедшего пользователя.

Очевидно, что учетная запись «Administrator» является администратором для всех трёх компьютеров. Пользователь «mnelson» является администратором на OPS-WS-002. Пользователь «jwarner» является администратором на IT-SRV-002.

На HR-WS-002 в систему вошел только «mnelson», на  OPS-WS-002 — «jwarner». На IT-SRV-002 авторизовались три пользователя: «rwinchester», «jfrank» и «Administrator». Пользователь «jdimmock» не является ни администратором, ни авторизованным пользователем.

Теперь у нас есть все, что нужно, чтобы найти кратчайший путь от любой вершины к любой другой.

Алгоритм Дейкстры

Алгоритм Дейкстры позволяет определить кратчайший путь к любой  вершины в графе — и он требует только n циклов , где n — число вершин в графе. Вот как работает алгоритм Дейкстры:

  1. Определите начальную вершину. Установите расстояние до нее как 0, до любой другой вершины — бесконечность.
  2. Среди всех не посещённых выберите вершину с наименьшим значением расстояния и сделайте её текущей вершиной.
  3. Рассмотрите рёбра текущей вершины. Для каждой смежной вершины сравните её расстояние со значением расстояния текущей вершины плюс один. Если это расчётное расстояние меньше, то замените на него значение смежной вершины и обновите значение предшественника смежной вершины на имя текущей вершины. Отметьте её как посещённую.
  4. Перейдите к шагу 2, пока не пройдёте через все вершины.

Screen-Shot-2016-02-15-at-1.54.32-PM-768x290

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

  1. Возьмите имя целевой вершины и добавьте его в массив пути.
  2. Возьмите последнюю добавленную вершину в массиве пути и найдите ее предшественника. Добавьте предшественника в массив пути.
  3. Повторяйте пункт 2, пока не останется ни одного предшественника. В этот момент мы достигли начальной вершины.

Screen-Shot-2016-02-14-at-10.54.27-PM-768x228

Заключение

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

Вы можете найти реализацию метода здесь:

https://github.com/andyrobbins/PowerPath