
Reconhecimento do Active Directory e auditoria de segurança somente leitura via ADWS (net.tcp/9389), em Go
adit é uma ferramenta de reconhecimento de Active Directory e de auditoria de segurança somente leitura, em binário único, que se comunica com um Domain Controller através de ADWS (Active Directory Web Services, TCP/9389) em vez de LDAP.
Um adit é a entrada horizontal de uma mina — o caminho silencioso para dentro. Consultar o AD através do ADWS em vez do LDAP/389 significa que o tráfego é enquadrado em WCF net.tcp, SOAP em binary-XML sobre uma porta incomum, pelo que é muito menos provável ser inspecionado, filtrado ou assinado do que o LDAP clássico — continuando a devolver os mesmos dados do diretório. O adit implementa a pilha completa do protocolo ADWS em Go, sem dependências externas de runtime.
┌────────────┐ net.tcp/9389 ┌──────────────┐
│ adit │ ───────────────▶ │ ADWS on DC │ ──▶ local LDAP
│ (Linux) │ NMF · NNS · │ (port 9389) │
│ │ NBFSE · SOAP └──────────────┘
└────────────┘
O adit é uma ferramenta defensiva/de auditoria e de avaliação autorizada. Execute-o apenas contra diretórios que está autorizado a avaliar.
| Capacidade | Detalhes |
|---|---|
| Transporte | ADWS sobre WCF net.tcp (TCP/9389) — enquadramento MC-NMF, handshake MS-NNS, binary XML MC-NBFS/NBFSE, SOAP WS-Enumeration/WS-Transfer |
| Autenticação | NTLMv2 (sign + seal) e Kerberos (ccache / keytab / password; RFC 4121 sealed GSS) |
| Coletores de recon | 31 módulos (ver abaixo) → CSV por módulo |
| Relatórios | Livro XLSX multi-folha estilizado + dashboard HTML autónomo (pesquisa/ordenação, badges de severidade, scroll-spy) |
| Auditoria de segurança | 27 regras somente leitura (incl. ADCS ESC1–4/9) → JSON classificado por severidade, também apresentado no dashboard |
| Proxy / jump host | HTTP CONNECT, SOCKS5/5h, SOCKS4/4a (com autenticação de proxy + DNS remoto) |
| Paginação | Paginação Pull do lado do servidor via WS-Enumeration, tamanho de página configurável |
| Relatórios offline | Reconstruir XLSX/HTML a partir de CSVs previamente recolhidos, sem necessidade de DC |
| Dependências | Go puro; sem biblioteca LDAP, sem .NET, sem serviços externos |
forest, domain, trusts, sites, subnets, schemahistory, dcs,
users, userspns, groups, computers, computerspns, ous, gpos,
gplinks, passwordpolicy, fgpp, dnszones, dnsrecords, kerberoastable,
asreproastable, krbtgt, adcs, cas, laps, protectedgroups,
groupmembers, gmsa, dmsa, printers, bitlocker
O ADCS (adcs) sinaliza ESC1–ESC4/ESC9; o laps reporta quem pode ler cada password; o protectedgroups audita os Protected Users. Execute adit -list-modules para a lista atual.
-audit executa 27 regras somente leitura. As descobertas incluem um id de regra, severidade, objetos afetados, evidência e remediação, e são escritas em Adit-Audit.json (e, quando combinado com -collect, numa secção "Audit Findings" que lidera o dashboard). O motor nunca lê valores de atributos secretos (LAPS / gMSA / BitLocker), embora os coletores de recon o possam fazer.
| Regra | Severidade | O que sinaliza |
|---|---|---|
| AD-DOM-010 | Critical | Direitos DCSync (replicação) detidos por um principal não-Tier-0 |
| AD-ACL-001/005/006/007/011–016 | Critical | Controlo perigoso (GenericAll/Write, WriteDACL/Owner, ForceChangePassword, Write SPN / KeyCredentialLink / member / AllowedToAct) sobre um objeto privilegiado |
| AD-SDH-001/002 | Critical | Controlo / proprietário inesperado do AdminSDHolder |
| AD-CS-001 | Critical–Medium | ESC1 — o template de certificado permite sujeito fornecido pelo requerente |
| AD-CS-002 | Critical–Medium | ESC2 — template de certificado Any-Purpose / sem EKU |
| AD-CS-003 | High–Medium | ESC3 — template Certificate Request Agent |
| AD-CS-004 | High | ESC4 — controlo de acesso fraco num template de certificado |
| AD-CS-009 | High | ESC9 — o template de certificado não tem a extensão de segurança |
| AD-CS-005 | Critical/High | ESC5 — controlo perigoso de um objeto PKI (NTAuthCertificates, CA store, objeto CA) |
| AD-CS-006 | Info | AD CS presente — ESC6/ESC7/ESC8 requerem verificação ao nível do host (não observável via ADWS) |
| AD-DOM-008 | High | Encriptação de password reversível ativada em todo o domínio |
| AD-USR-001 | High | Pré-autenticação Kerberos desativada (AS-REP roastable) |
| AD-USR-009 | High | A conta usa apenas encriptação DES |
| AD-CMP-006 | High | Delegação não restrita num não-DC |
| AD-KCL-001 | High | Key Credential (shadow credential) numa conta privilegiada |
| AD-KRB-001 | High | A password do krbtgt está obsoleta |
| AD-DOM-005 | Medium | Machine Account Quota > 0 (qualquer utilizador pode juntar computadores) |
| AD-USR-002 | Medium | Conta de serviço Kerberoastable (High se privilegiada) |
| AD-USR-005 | Medium | PASSWD_NOTREQD definido |
| AD-USR-006 | Medium | Password de conta privilegiada nunca expira |
| AD-USR-011 | Medium | Password de conta privilegiada obsoleta |
| AD-CMP-008 | Medium | Delegação restrita baseada em recursos configurada |
| AD-CMP-012 | Medium | Sistema operativo legado / não suportado |
| AD-GRP-009 | Medium | Principal de segurança externo num grupo privilegiado |
| AD-GRP-020 | Medium | Associação privilegiada oculta via primaryGroupID |
| AD-TRU-001/003 | High/Medium | Confiança sem filtragem de SID / com histórico de SID |
| AD-DNS-003/004 | Medium/Low | Registo WPAD / ISATAP presente |
| AD-CMP-011 | Low | Conta de computador obsoleta |
| AD-INT-005 | High | sIDHistory contém um SID privilegiado |
Os limiares são ajustáveis: -krbtgt-max-age, -priv-pwd-max-age, -stale-days.
Nota sobre ADCS: ESC1–ESC5 e ESC9 são avaliados a partir de objetos AD via ADWS. ESC6 (
EDITF_ATTRIBUTESUBJECTALTNAME2), ESC7 (ACLs de funções da CA) e ESC8 (web enrollment / NTLM relay) residem no registo/endpoints HTTP do host da CA e não são observáveis via ADWS —AD-CS-006sinaliza que existe uma CA para que possam ser verificados no host (por exemplo, com o Certipy).
Requer Go 1.26+. Sem outras dependências de compilação.
# Build the binary
go build -o adit ./cmd/adit
./adit -version
# …or run without installing
go run ./cmd/adit -h
# Cross-compile release archives for linux/windows/darwin (amd64+arm64) into dist/
bash scripts/build-release.sh
-fqdn deve ser o FQDN real do DC (não o seu IP): o cabeçalho SOAP To do ADWS é comparado com o endpoint pelo AddressFilter do WCF. Encontre-o com, por exemplo, nslookup -type=SRV _ldap._tcp.dc._msdcs.<domain> <dc-ip>.
adit -dc <host> -fqdn <dc-fqdn> -d <DOMAIN> -u <user> -p <pass> [flags]
# RootDSE handshake only (verifies auth + the full protocol stack)
adit -dc 10.0.0.10 -fqdn dc01.example.local -d EXAMPLE.LOCAL -u user -p 'pass'
# Run every collector -> ./report/CSV-Files/*.csv + Adit-Report.{xlsx,html}
adit -dc 10.0.0.10 -fqdn dc01.example.local -d EXAMPLE.LOCAL -u user -p 'pass' \
-collect all -o ./report
# A subset of collectors
adit -dc 10.0.0.10 -fqdn dc01.example.local -d EXAMPLE.LOCAL -u user -p 'pass' \
-collect users,groups,computers,kerberoastable