Skip to content

Commit a7c0155

Browse files
committed
Implemented custom DNS resolver with --dns / --dns-tcp, DC discovery, updated go-adws version and README.
1 parent c6d76f7 commit a7c0155

7 files changed

Lines changed: 245 additions & 124 deletions

File tree

README.md

Lines changed: 87 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -46,50 +46,51 @@ $ go install github.com/Macmod/sopa/cmd/sopa@latest
4646
# Auth flags (-u, -p, -d, -k, -H, -c, ...) are omitted for brevity — see Authentication section.
4747

4848
# Search objects by LDAP filter
49-
$ sopa query --dc <DC> --filter '(objectClass=*)'
49+
$ sopa [auth_flags] query --dc <DC> --filter '(objectClass=*)'
5050

5151
# Fetch a single object by DN
52-
$ sopa get --dc <DC> --dn '<DN>'
52+
$ sopa [auth_flags] get --dc <DC> --dn '<DN>'
5353

5454
# Delete an object by DN
55-
$ sopa delete --dc <DC> --dn '<DN>'
55+
$ sopa [auth_flags] delete --dc <DC> --dn '<DN>'
5656

5757
# Edit attribute values
58-
$ sopa attr add --dc <DC> --dn '<DN>' --attr <ATTR> --value <VALUE>
59-
$ sopa attr replace --dc <DC> --dn '<DN>' --attr <ATTR> --value <VALUE>
60-
$ sopa attr delete --dc <DC> --dn '<DN>' --attr <ATTR>
58+
$ sopa [auth_flags] attr add --dc <DC> --dn '<DN>' --attr <ATTR> --value <VALUE>
59+
$ sopa [auth_flags] attr replace --dc <DC> --dn '<DN>' --attr <ATTR> --value <VALUE>
60+
$ sopa [auth_flags] attr delete --dc <DC> --dn '<DN>' --attr <ATTR>
6161

6262
# Create objects
63-
$ sopa create user --dc <DC> --name <CN> --pass <INITIAL_PASS>
64-
$ sopa create computer --dc <DC> --name <CN>
65-
$ sopa create group --dc <DC> --name <CN> --type GlobalSecurity
66-
$ sopa create ou --dc <DC> --name <CN>
67-
$ sopa create container --dc <DC> --name <CN>
68-
$ sopa create custom --dc <DC> --template <TEMPLATE.yaml>
63+
$ sopa [auth_flags] create user --dc <DC> --name <CN> --pass <INITIAL_PASS>
64+
$ sopa [auth_flags] create computer --dc <DC> --name <CN>
65+
$ sopa [auth_flags] create group --dc <DC> --name <CN> --type GlobalSecurity
66+
$ sopa [auth_flags] create ou --dc <DC> --name <CN>
67+
$ sopa [auth_flags] create container --dc <DC> --name <CN>
68+
$ sopa [auth_flags] create custom --dc <DC> --template <TEMPLATE.yaml>
6969

7070
# Set / change account passwords (MS-ADCAP)
71-
$ sopa set-password --dc <DC_FQDN> --dn '<DN>' --new <NEW_PASS>
72-
$ sopa change-password --dc <DC_FQDN> --dn '<DN>' --old <OLD_PASS> --new <NEW_PASS>
71+
$ sopa [auth_flags] set-password --dc <DC> --dn '<DN>' --new <NEW_PASS>
72+
$ sopa [auth_flags] change-password --dc <DC> --dn '<DN>' --old <OLD_PASS> --new <NEW_PASS>
7373

7474
# Translate DN <-> canonical name (MS-ADCAP)
75-
$ sopa translate-name --dc <DC_FQDN> --offered DistinguishedName --desired CanonicalName '<DN>'
75+
# (this call is mostly useless but kept for completeness 😄)
76+
$ sopa [auth_flags] translate-name --dc <DC> --offered DistinguishedName --desired CanonicalName '<DN>'
7677

7778
# Principal group memberships (MS-ADCAP)
78-
$ sopa groups --dc <DC_FQDN> --dn '<DN>' --membership --authz
79+
$ sopa [auth_flags] groups --dc <DC> --dn '<DN>' --membership --authz
7980

8081
# Group members (MS-ADCAP)
81-
$ sopa members --dc <DC_FQDN> --dn '<GROUP_DN>' --recursive
82+
$ sopa [auth_flags] members --dc <DC> --dn '<GROUP_DN>' --recursive
8283

8384
# Toggle optional AD feature, e.g. Recycle Bin (MS-ADCAP)
84-
$ sopa optfeature --dc <DC_FQDN> --feature-id <FEATURE_GUID> --enable
85+
$ sopa [auth_flags] optfeature --dc <DC> --feature-id <FEATURE_GUID> --enable
8586

8687
# Topology info (MS-ADCAP)
87-
$ sopa info version --dc <DC_FQDN>
88-
$ sopa info domain --dc <DC_FQDN>
89-
$ sopa info forest --dc <DC_FQDN>
90-
$ sopa info dcs --dc <DC_FQDN>
88+
$ sopa [auth_flags] info version --dc <DC>
89+
$ sopa [auth_flags] info domain --dc <DC>
90+
$ sopa [auth_flags] info forest --dc <DC>
91+
$ sopa [auth_flags] info dcs --dc <DC>
9192

92-
# ADWS service endpoint metadata (unauthenticated)
93+
# ADWS service endpoint metadata (unauthenticated - auth flags not needed)
9394
$ sopa mex --dc <DC>
9495
```
9596

@@ -129,29 +130,78 @@ Notes:
129130
- `hex` values are converted to `xsd:base64Binary`.
130131
- To set an empty string explicitly, use `value: ""`.
131132

133+
## DC discovery & DNS
134+
135+
`--dc` accepts a **FQDN**, an **IP address**, or can be **omitted**.
136+
Because the DC's hostname is sometimes not available from the network's default DNS, it is strongly recommended to always pass `--dns <DC-IP>` so that sopa uses the DC's own DNS server for all lookups:
137+
138+
```bash
139+
# Option 1: let sopa resolve everything through the DC's DNS
140+
$ sopa query --dns 192.168.1.10 -d corp.local -u user -p pass --filter '(objectClass=user)'
141+
```
142+
143+
When `--dc` is omitted and `--domain` is provided, sopa discovers a DC
144+
automatically by querying SRV records:
145+
146+
```
147+
_ldap._tcp.<domain> (tried first)
148+
_kerberos._tcp.<domain> (fallback)
149+
```
150+
151+
The target of the highest-priority record is used. This requires that the
152+
DNS server pointed to by `--dns` can answer those SRV queries — the DC's own
153+
integrated DNS server (when present) should be capable of that.
154+
155+
```bash
156+
# Option 2: provide DC explicitly without Kerberos
157+
$ sopa info version --dc 192.168.1.10 --domain corp.local -u user -p pass
158+
```
159+
160+
When an IP is provided for `--dc` and Kerberos is in use, the IP is resolved to an FQDN via a **reverse PTR lookup** so that the Kerberos SPN / KDC address are correct.
161+
This PTR lookup also goes through `--dns`, so a correctly configured reverse
162+
zone on the DC is required:
163+
164+
```bash
165+
# Option 3: IP input + Kerberos: PTR lookup resolves 192.168.1.10 -> dc.corp.local
166+
$ sopa info version --dc 192.168.1.10 --dns 192.168.1.10 -k --domain corp.local -u user -p pass
167+
```
168+
169+
When Kerberos is not in use, there is no PTR lookup — the raw IP is used throughout.
170+
171+
All DNS operations in the stack - DC discovery, PTR resolution, ADWS TCP dial,
172+
and Kerberos KDC connections - use the same resolver built from `--dns` /
173+
`--dns-tcp`.
174+
175+
| Flag | Description |
176+
|------|-------------|
177+
| `--dns <host[:port]>` | Custom DNS server for all lookups (SRV, PTR, forward). Defaults to port 53. |
178+
| `--dns-tcp` | Force DNS queries over TCP instead of UDP. Useful when UDP is blocked or SRV responses are large. |
179+
| `--dns-timeout <duration>` | Timeout for DNS operations (default 10s). |
180+
| `--tcp-timeout <duration>` | Timeout for TCP dial and ADWS protocol operations (default 30s). |
181+
132182
# Authentication
133183

134184
`sopa` supports the following credential modes:
135185

136186
```bash
137187
# Password
138-
$ sopa <action> --dc <DC> -u <USER> -p <PASS> -d <DOMAIN> ...
188+
$ sopa --dc <DC> -d <DOMAIN> -u <USER> -p <PASS> <subcommand> [...]
139189

140190
# NT hash
141-
$ sopa <action> --dc <DC> -u <USER> -H <NT_HASH> -d <DOMAIN> ...
191+
$ sopa --dc <DC> -d <DOMAIN> -u <USER> -H <NT_HASH> <subcommand> [...]
142192

143-
# AES session key (DC must be FQDN; Kerberos is implied)
193+
# AES session key (Kerberos is implied)
144194
# 32 hex chars = AES-128, 64 hex chars = AES-256
145-
$ sopa <action> --dc <DC_FQDN> -u <USER> --aes-key <HEX_KEY> -d <DOMAIN> ...
195+
$ sopa --dc <DC> -d <DOMAIN> -u <USER> --aes-key <HEX_KEY> <subcommand> [...]
146196

147-
# Kerberos ccache (DC must be FQDN; Kerberos is implied)
148-
$ sopa <action> --dc <DC_FQDN> -u <USER> -c <CCACHE_PATH> -d <DOMAIN> ...
197+
# Kerberos ccache (Kerberos is implied)
198+
$ sopa --dc <DC> -d <DOMAIN> -u <USER> -c <CCACHE_PATH> <subcommand> [...]
149199

150-
# PFX certificate
151-
$ sopa <action> --dc <DC_FQDN> -u <USER> --pfx <CERT.pfx> --pfx-password <PFX_PASS> -d <DOMAIN> ...
200+
# PFX certificate (Kerberos is implied / via PKINIT)
201+
$ sopa --dc <DC> -d <DOMAIN> -u <USER> --pfx <CERT.pfx> --pfx-password <PFX_PASS> <subcommand> [...]
152202

153-
# PEM certificate
154-
$ sopa <action> --dc <DC_FQDN> -u <USER> --cert <CERT.pem> --key <KEY.pem> -d <DOMAIN> ...
203+
# PEM certificate (Kerberos is implied / via PKINIT)
204+
$ sopa --dc <DC> -d <DOMAIN> -u <USER> --cert <CERT.pem> --key <KEY.pem> <subcommand> [...]
155205
```
156206

157207
# Contributing
@@ -167,6 +217,10 @@ The idea to write this tool came from a wave of ADWS-focused tools, mainly for e
167217
* [FalconForceTeam/SOAPHound](https://github.com/FalconForceTeam/SOAPHound)
168218
* [mverschu/adwsdomaindump](https://github.com/mverschu/adwsdomaindump)
169219

220+
# SOCKS support
221+
222+
SOCKS is currently not implemented. Use a solution like [OkamiW/proxy-ns](https://github.com/OkamiW/proxy-ns) if needed for your use case.
223+
170224
# Acknowledgements
171225

172226
* Big thanks to [oiweiwei](https://github.com/oiweiwei) for [go-msrpc](https://github.com/oiweiwei/go-msrpc), as his `ssp` package implemented the authentication flow with GSSAPI seamlessly.

0 commit comments

Comments
 (0)