
Практический клиент для ADWS на Golang.
Практичный клиент для ADWS на Golang.
Sopa реализует стек протоколов ADWS (MS-NNS + MC-NMF + SOAP), предоставляя следующие функции командной строки:
query: выполняет поиск по LDAP-фильтру через цикл WS-Enumeration Enumerate + Pull с проекцией атрибутов, контролем области видимости (Base/OneLevel/Subtree) и пагинациейget: получает один объект по DN через WS-Transfer Getcreate: создаёт объекты через WS-Transfer ResourceFactory (встроенные типы: user, computer, group, OU, container; или пользовательские объекты из YAML-шаблона через IMDA AddRequest)delete: удаляет объект по DN через WS-Transfer Deleteattr: добавляет, заменяет или удаляет отдельные значения атрибутов существующего объекта через WS-Transfer Put$ go install github.com/Macmod/sopa/cmd/sopa@latest
# Auth flags (-u, -p, -d, -k, -H, -c, ...) are omitted for brevity - see Authentication section.
# Search objects by LDAP filter
$ sopa [auth_flags] query --dc <DC> --filter '(objectClass=*)'
# Fetch a single object by DN
$ sopa [auth_flags] get --dc <DC> --dn '<DN>'
# Delete an object by DN
$ sopa [auth_flags] delete --dc <DC> --dn '<DN>'
# Edit attribute values
$ sopa [auth_flags] attr add --dc <DC> --dn '<DN>' --attr <ATTR> --value <VALUE>
$ sopa [auth_flags] attr replace --dc <DC> --dn '<DN>' --attr <ATTR> --value <VALUE>
$ sopa [auth_flags] attr delete --dc <DC> --dn '<DN>' --attr <ATTR>
# Create objects
$ sopa [auth_flags] create user --dc <DC> --name <CN> --pass <INITIAL_PASS>
$ sopa [auth_flags] create computer --dc <DC> --name <CN>
$ sopa [auth_flags] create group --dc <DC> --name <CN> --type GlobalSecurity
$ sopa [auth_flags] create ou --dc <DC> --name <CN>
$ sopa [auth_flags] create container --dc <DC> --name <CN>
$ sopa [auth_flags] create custom --dc <DC> --template <TEMPLATE.yaml>
# Set / change account passwords (MS-ADCAP)
$ sopa [auth_flags] set-password --dc <DC> --dn '<DN>' --new <NEW_PASS>
$ sopa [auth_flags] change-password --dc <DC> --dn '<DN>' --old <OLD_PASS> --new <NEW_PASS>
# Translate DN <-> canonical name (MS-ADCAP)
# (этот вызов в основном бесполезен, но сохранён для полноты 😄)
$ sopa [auth_flags] translate-name --dc <DC> --offered DistinguishedName --desired CanonicalName '<DN>'
# Principal group memberships (MS-ADCAP)
$ sopa [auth_flags] groups --dc <DC> --dn '<DN>' --membership --authz
# Group members (MS-ADCAP)
$ sopa [auth_flags] members --dc <DC> --dn '<GROUP_DN>' --recursive
# Toggle optional AD feature, e.g. Recycle Bin (MS-ADCAP)
$ sopa [auth_flags] optfeature --dc <DC> --feature-id <FEATURE_GUID> --enable
# Topology info (MS-ADCAP)
$ sopa [auth_flags] info version --dc <DC>
$ sopa [auth_flags] info domain --dc <DC>
$ sopa [auth_flags] info forest --dc <DC>
$ sopa [auth_flags] info dcs --dc <DC>
# ADWS service endpoint metadata (unauthenticated - auth flags not needed)
$ sopa mex --dc <DC>
Запустите sopa без подкоманды, чтобы открыть интерактивную оболочку. Она использует одно соединение для всех команд и поддерживает автодополнение.
$ sopa --dc <DC> -u <USER> -p <PASS> -d <DOMAIN>
sopa v1.1.0
Connected dc.corp.local domain=corp.local user=Administrator
Type 'help' for commands or 'exit' to quit.
[corp.local]> query --filter '(objectClass=user)' --attrs sAMAccountName
[corp.local]> get --dn 'CN=Administrator,CN=Users,DC=corp,DC=local'
[corp.local]> exit
Используйте exit, quit или Ctrl-D для выхода из оболочки.
Пример шаблона: examples/custom-create.example.yaml
Схема шаблона (YAML):
parentDN (string, required): DN контейнераrdn (string, required): относительное DN нового объекта (например, CN=Foo)attributes (list, required): каждый элемент имеет:
name (string, required): имя атрибута (cn или addata:cn)type (string, optional): string|int|bool|base64|hex (или явный xsd:*), по умолчанию stringvalue (string) или values (list of strings)Примечания:
ad:relativeDistinguishedName или ad:container-hierarchy-parent в шаблон (они добавляются автоматически).hex преобразуются в xsd:base64Binary.value: "".--dc принимает FQDN, IP-адрес или может быть опущен.
Поскольку имя хоста контроллера домена иногда недоступно из DNS сети по умолчанию, настоятельно рекомендуется всегда указывать --dns <DC-IP>, чтобы sopa использовала собственный DNS-сервер контроллера домена для всех запросов:
# Option 1: let sopa resolve everything through the DC's DNS
$ sopa query --dns 192.168.1.10 -d corp.local -u user -p pass --filter '(objectClass=user)'
Когда --dc опущен и указан --domain, sopa автоматически обнаруживает контроллер домена, запрашивая SRV-записи:
_ldap._tcp.<domain> (tried first)
_kerberos._tcp.<domain> (fallback)
Используется цель записи с наивысшим приоритетом. Это требует, чтобы DNS-сервер, указанный в --dns, мог отвечать на эти SRV-запросы — собственный интегрированный DNS-сервер контроллера домена (если он есть) должен быть на это способен.
# Option 2: provide DC explicitly without Kerberos
$ sopa info version --dc 192.168.1.10 --domain corp.local -u user -p pass
Когда для --dc указан IP, он всегда разрешается в FQDN через обратный PTR-запрос — фильтр адресов WCF конечной точки ADWS требует FQDN в заголовке wsa:To независимо от метода аутентификации.
Этот PTR-запрос также проходит через --dns, поэтому требуется правильно настроенная обратная зона на контроллере домена:
# Option 3: IP input - PTR lookup resolves 192.168.1.10 -> dc.corp.local
$ sopa info version --dc 192.168.1.10 --dns 192.168.1.10 --domain corp.local -u user -p pass
Все DNS-операции в стеке — обнаружение контроллера домена, разрешение PTR, TCP-соединение ADWS и соединения с KDC Kerberos — используют один и тот же резолвер, построенный из --dns / --dns-tcp.
sopa поддерживает следующие способы аутентификации:
# Password
$ sopa --dc <DC> -d <DOMAIN> -u <USER> -p <PASS> <subcommand> [...]
# NT hash
$ sopa --dc <DC> -d <DOMAIN> -u <USER> -H <NT_HASH> <subcommand> [...]
# AES session key (Kerberos is implied)
# 32 hex chars = AES-128, 64 hex chars = AES-256
$ sopa --dc <DC> -d <DOMAIN> -u <USER> --aes-key <HEX_KEY> <subcommand> [...]
# Kerberos ccache (Kerberos is implied)
$ sopa --dc <DC> -d <DOMAIN> -u <USER> -c <CCACHE_PATH> <subcommand> [...]
# PFX certificate (Kerberos is implied / via PKINIT)
$ sopa --dc <DC> -d <DOMAIN> -u <USER> --pfx <CERT.pfx> --pfx-password <PFX_PASS> <subcommand> [...]
# PEM certificate (Kerberos is implied / via PKINIT)
$ sopa --dc <DC> -d <DOMAIN> -u <USER> --cert <CERT.pem> --key <KEY.pem> <subcommand> [...]
Все TCP-соединения (ADWS, Kerberos, DNS) могут быть туннелированы через прокси SOCKS5 с помощью -x / --socks5:
# Route everything through a SOCKS5 proxy
$ sopa -x 127.0.0.1:1080 --dc dc.corp.local -d corp.local -u user -p pass query --filter '(objectClass=user)'
# Use the DC's own DNS through the proxy, then connect via proxy
$ sopa -x 127.0.0.1:1080 --dns 192.168.1.10 --dc 192.168.1.10 -d corp.local -u user -p pass query --filter '(objectClass=user)'
# Keep DNS local (e.g. DNS already reachable without proxy), only proxy TCP connections
$ sopa -x 127.0.0.1:1080 --no-proxy-dns --dc dc.corp.local -d corp.local -u user -p pass query --filter '(objectClass=user)'
Приветствуется ваш вклад через открытие issue или отправку pull request.
Идея написать этот инструмент возникла из волны инструментов, ориентированных на ADWS, в основном для целей обхода. Теоретически всё, что можно сделать с их помощью, можно сделать и с sopa, но если вы хотите выполнять более сложные/специфические действия, ознакомьтесь и с ними:
ssp реализовал поток аутентификации с GSSAPI без проблем.Лицензия MIT (MIT)
Авторское право (c) 2023 Artur Henrique Marzano Gonzaga
Настоящим предоставляется разрешение, безвозмездно, любому лицу, получившему копию этого программного обеспечения и связанных с ним файлов документации (далее — «Программное обеспечение»), на использование Программного обеспечения без ограничений, включая, без ограничений, права на использование, копирование, изменение, слияние, публикацию, распространение, сублицензирование и/или продажу копий Программного обеспечения, а также на разрешение лицам, которым предоставляется Программное обеспечение, делать это при соблюдении следующих условий:
Указанное выше уведомление об авторских правах и данное уведомление о разрешении должны быть включены во все копии или существенные части Программного обеспечения.
ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ «КАК ЕСТЬ», БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, ЯВНЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ, ГАРАНТИЯМИ ТОВАРНОЙ ПРИГОДНОСТИ, ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЁННОЙ ЦЕЛИ И ОТСУТСТВИЯ НАРУШЕНИЙ. НИ В КОЕМ СЛУЧАЕ АВТОРЫ ИЛИ ДЕРЖАТЕЛИ АВТОРСКИХ ПРАВ НЕ НЕСУТ ОТВЕТСТВЕННОСТИ ПО КАКИМ-ЛИБО ИСКАМ, УБЫТКАМ ИЛИ ИНЫМ ОБЯЗАТЕЛЬСТВАМ, ВОЗНИКШИМ В РЕЗУЛЬТАТЕ ДОГОВОРА, ДЕЛИКТА ИЛИ ИНОГО ДЕЙСТВИЯ, ВЫТЕКАЮЩЕГО ИЗ ИЛИ В СВЯЗИ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ, ЕГО ИСПОЛЬЗОВАНИЕМ ИЛИ ИНЫМИ ДЕЙСТВИЯМИ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ.
set-password: устанавливает пароль учётной записи через MS-ADCAP SetPasswordchange-password: изменяет пароль учётной записи (требуется старый пароль) через MS-ADCAP ChangePasswordtranslate-name: преобразует между форматами DN и канонического имени через TranslateNamegroups: выводит членство в группах или группы авторизации участника через GetADPrincipalGroupMembership / GetADPrincipalAuthorizationGroupmembers: перечисляет членов группы (опционально рекурсивно) через GetADGroupMemberoptfeature: включает/отключает дополнительные функции AD (например, Корзину) через ChangeOptionalFeatureinfo: получает метаданные топологии (версия, домен, лес, список контроллеров домена) через GetVersion, GetADDomain, GetADForest, GetADDomainControllersmex: получает метаданные конечной точки службы ADWS через неаутентифицированный запрос WS-MetadataExchange| Флаг | Описание |
|---|
--dns <host[:port]> | Пользовательский DNS-сервер для всех запросов (SRV, PTR, прямые). По умолчанию порт 53. |
--dns-tcp | Принудительное использование TCP вместо UDP для DNS-запросов. Полезно, если UDP заблокирован или ответы SRV большие. |
-x / --socks5 <host:port> | Маршрутизировать все TCP-соединения через прокси SOCKS5. DNS-запросы также туннелируются через прокси, если не установлен --no-proxy-dns. |
--no-proxy-dns | Когда активен --socks5, разрешать DNS через локальный системный резолвер вместо прокси. |
--dns-timeout <duration> | Тайм-аут для DNS-операций (по умолчанию 10 с). |
--tcp-timeout <duration> | Тайм-аут для TCP-подключения и операций протокола ADWS (по умолчанию 30 с). |