Projetando aplicativos para serem executados em um nível de integridade baixo
Uma maneira fácil de executar um processo de aplicativo em um nível de integridade baixo é definir o nível de integridade do arquivo de programa executável como de baixa integridade. Quando esse arquivo de imagem é iniciado, o processo do aplicativo é iniciado com um nível de integridade baixo. Por exemplo, suponha que queremos executar o aplicativo Calculadora do Windows em um processo de baixa integridade.
Para executar calc.exe com baixa integridade
Faça uma cópia de c:\Windows\system32\calc.exe para uma pasta temporária.
Use o programa icacls para definir o nível de integridade do arquivo temporário, lowcalc.exe, para baixa integridade usando o comando icacls:
icacls lowcalc.exe /setintegritylevel Low
Execute a versão de baixa integridade do calc.exe.
A imagem a seguir mostra as etapas para executar a Calculadora do Windows em um processo de baixa integridade.
Figura 9 Iniciando a Calculadora do Windows com baixa integridade
Você pode usar o Process Explorer para confirmar se o arquivo de imagem, lowcalc.exe, está realmente em execução com baixa integridade. A coluna Nível de Integridade está no lado direito da imagem.
Figura 10 Processo de calculadora baixa
Nem todos os programas de aplicativo serão executados corretamente em um processo de baixa integridade. Um processo de baixa integridade não tem acesso de gravação à maioria das áreas na área de perfil local do usuário do sistema de arquivos ou no registro em HKCU. A incapacidade de um processo de baixa integridade de obter acesso de gravação ao perfil do usuário é uma coisa boa se o programa for um software mal-intencionado indesejado. No entanto, para aplicativos como o modo protegido internet Explorer, talvez seja necessário reprojetar todos os recursos do aplicativo se comportando corretamente.
Use ferramentas úteis, como o Monitor de Processo do Sysinternals.com para ter uma ideia de quais recursos de arquivo e registro um aplicativo usa atualmente para acesso de gravação que falhará ao executar com baixa integridade.
Embora seja possível alterar um aplicativo para ser executado inteiramente com baixa integridade, alguns recursos do aplicativo podem funcionar corretamente somente quando são implementados em um processo de integridade média. Um aplicativo em execução com baixa integridade pode ter uma parte do aplicativo em um processo de baixa integridade, por exemplo, para lidar com dados não confiáveis da Internet. Outra parte do aplicativo pode ser implementada em um processo de "agente" de integridade média para lidar com um pequeno conjunto de ações iniciadas pelo usuário. A comunicação entre os processos de integridade média e de baixa integridade no aplicativo pode ser tratada usando vários mecanismos de IPC. A parte de integridade média do aplicativo deve assumir que todos os dados e código no processo de baixa integridade não são confiáveis.
O modo protegido internet Explorer é um aplicativo reprojetado para ser executado em um processo de baixa integridade. Para obter mais informações sobre Explorer de Internet no Modo Protegido, consulte Noções básicas e trabalhando no modo protegido Explorer internet (https://go.microsoft.com/fwlink/?LinkId=90931).
Os tópicos main para criar um aplicativo a ser executado com baixa integridade são os seguintes:
- Iniciando um processo filho com baixa integridade
- Locais graváveis para aplicativos de baixa integridade
- Comunicação entre processos de baixa integridade e de nível superior
Iniciando um processo com baixa integridade
Por padrão, os processos filho herdam o nível de integridade do processo pai. Para iniciar um processo de baixa integridade, você deve iniciar um novo processo filho com um token de acesso de baixa integridade usando a função CreateProcessAsUser. Para iniciar um processo de baixa integridade de um processo de integridade média, você deve iniciar o novo processo explicitamente como de baixa integridade.
Para iniciar um processo de baixa integridade
Duplicar o identificador do processo atual, que está no nível de integridade médio.
Use SetTokenInformation para definir o nível de integridade no token de acesso como Baixo.
Use CreateProcessAsUser para criar um novo processo usando o identificador para o token de acesso de baixa integridade.
CreateProcessAsUser atualiza o descritor de segurança no novo processo filho e o descritor de segurança para que o token de acesso corresponda ao nível de integridade do token de acesso de baixa integridade.
O exemplo de código a seguir demonstra esse processo.
void CreateLowProcess()
{
BOOL fRet;
HANDLE hToken = NULL;
HANDLE hNewToken = NULL;
PSID pIntegritySid = NULL;
TOKEN_MANDATORY_LABEL TIL = {0};
PROCESS_INFORMATION ProcInfo = {0};
STARTUPINFO StartupInfo = {0};
// Notepad is used as an example
WCHAR wszProcessName[MAX_PATH] =
L"C:\\Windows\\System32\\Notepad.exe";
// Low integrity SID
WCHAR wszIntegritySid[20] = L"S-1-16-1024";
PSID pIntegritySid = NULL;
fRet = OpenProcessToken(GetCurrentProcess(),
TOKEN_DUPLICATE |
TOKEN_ADJUST_DEFAULT |
TOKEN_QUERY |
TOKEN_ASSIGN_PRIMARY,
&hToken);
if (!fRet)
{
goto CleanExit;
}
fRet = DuplicateTokenEx(hToken,
0,
NULL,
SecurityImpersonation,
TokenPrimary,
&hNewToken);
if (!fRet)
{
goto CleanExit;
}
fRet = ConvertStringSidToSid(wszIntegritySid, &pIntegritySid);
if (!fRet)
{
goto CleanExit;
}
TIL.Label.Attributes = SE_GROUP_INTEGRITY;
TIL.Label.Sid = pIntegritySid;
//
// Set the process integrity level
//
fRet = SetTokenInformation(hNewToken,
TokenIntegrityLevel,
&TIL,
sizeof(TOKEN_MANDATORY_LABEL) + GetLengthSid(pIntegritySid));
if (!fRet)
{
goto CleanExit;
}
//
// Create the new process at Low integrity
//
fRet = CreateProcessAsUser(hNewToken,
NULL,
wszProcessName,
NULL,
NULL,
FALSE,
0,
NULL,
NULL,
&StartupInfo,
&ProcInfo);
CleanExit:
if (ProcInfo.hProcess != NULL)
{
CloseHandle(ProcInfo.hProcess);
}
if (ProcInfo.hThread != NULL)
{
CloseHandle(ProcInfo.hThread);
}
LocalFree(pIntegritySid);
if (hNewToken != NULL)
{
CloseHandle(hNewToken);
}
if (hToken != NULL)
{
CloseHandle(hToken);
}
return fRet;
}
Locais graváveis com baixa integridade
O Windows Vista tem locais específicos de arquivo e registro que recebem rótulos baixos obrigatórios para permitir acesso de gravação de aplicativos de baixa integridade. A Tabela 10 mostra esses locais graváveis.
Tabela 10 Locais que podem ser gravados para rótulos baixos obrigatórios
Localização | Área gravável |
---|---|
Registro |
Processos de baixa integridade podem gravar e criar subchaves em HKEY_CURRENT_USER\Software\AppDataLow |
Sistema de arquivos |
Processos de baixa integridade podem gravar e criar subpastas em %USER PROFILE%\AppData\LocalLow |
Reduzir um rótulo obrigatório de recurso
Devido a possíveis riscos de segurança, não recomendamos que você crie um processo de maior integridade para aceitar a entrada ou compartilhar recursos com processos de baixa integridade. O processo de baixa integridade pode tentar um comportamento mal-intencionado. No entanto, talvez seja necessário executar essa ação por design.
Observação
Os aplicativos que aceitam a entrada ou compartilham recursos com processos de integridade inferior devem assumir que os dados fornecidos por processos de integridade inferior não são confiáveis e, em seguida, devem executar a validação apropriada. Por exemplo, o modo protegido internet Explorer exibe a caixa de diálogo Salvar como do processo internet Explorer agente de usuário. Isso permite que os usuários confirmem que desejam salvar um arquivo usando um processo que é executado com direitos mais altos do que o modo protegido Explorer internet.
Como aplicativos de baixa integridade podem gravar apenas em recursos de baixa integridade, você precisa reduzir o nível de integridade dos recursos compartilhados.
Para reduzir o nível de integridade dos recursos compartilhados
Crie um descritor de segurança SDDL que define um rótulo obrigatório baixo.
Converta a cadeia de caracteres SDDL em um descritor de segurança.
Atribua o atributo de baixa integridade ao descritor de segurança.
Atribua o descritor de segurança ao recurso compartilhado.
O exemplo de código a seguir mostra esse processo.
#include <sddl.h>
#include <AccCtrl.h>
#include <Aclapi.h>
void SetLowLabelToFile()
{
// The LABEL_SECURITY_INFORMATION SDDL SACL to be set for low integrity
#define LOW_INTEGRITY_SDDL_SACL_W L"S:(ML;;NW;;;LW)"
DWORD dwErr = ERROR_SUCCESS;
PSECURITY_DESCRIPTOR pSD = NULL;
PACL pSacl = NULL; // not allocated
BOOL fSaclPresent = FALSE;
BOOL fSaclDefaulted = FALSE;
LPCWSTR pwszFileName = L"Sample.txt";
if (ConvertStringSecurityDescriptorToSecurityDescriptorW(
LOW_INTEGRITY_SDDL_SACL_W, SDDL_REVISION_1, &pSD, NULL))
{
if (GetSecurityDescriptorSacl(pSD, &fSaclPresent, &pSacl,
&fSaclDefaulted))
{
// Note that psidOwner, psidGroup, and pDacl are
// all NULL and set the new LABEL_SECURITY_INFORMATION
dwErr = SetNamedSecurityInfoW((LPWSTR) pwszFileName,
SE_FILE_OBJECT, LABEL_SECURITY_INFORMATION,
NULL, NULL, NULL, pSacl);
}
LocalFree(pSD);
}
}
Os processos de aplicativo podem definir a integridade de objetos protegíveis apenas para níveis no nível de integridade ou abaixo do nível de integridade do processo do aplicativo.
Comunicação entre processos de baixa integridade e de maior integridade
Os processos de baixa integridade não são completamente isolados de outros aplicativos. Eles podem interagir com outros processos. Na verdade, sem algumas formas de colaboração, os aplicativos em execução com baixa integridade podem parecer que o usuário está completamente quebrado.
Algumas formas de IPC estão disponíveis para processos de baixa integridade se comunicarem com processos de maior integridade. Os componentes no Windows Vista bloqueiam os seguintes tipos de comunicação.
A maioria das mensagens de janela e ganchos de processo são bloqueados pela UIPI.
Abrir um processo e usar CreateRemoteThread é bloqueado pelo rótulo obrigatório em objetos de processo.
A abertura de uma seção de memória compartilhada para acesso de gravação está bloqueada.
O uso de um objeto nomeado criado por um processo de integridade mais alto para sincronização é bloqueado pelo rótulo obrigatório padrão.
A associação a uma instância em execução de um serviço COM é bloqueada.
No entanto, você pode usar outros tipos de comunicação entre um processo de baixa integridade e um processo de maior integridade. Os tipos de comunicação que você pode usar incluem:Área de transferência (copiar e colar)
RPC (Chamada de Procedimento Remoto)
Soquetes
Mensagens de janela que o processo de maior integridade foi explicitamente autorizado a receber de processos de menor integridade chamando ChangeWindowMessageFilter
Memória compartilhada, em que o processo de integridade superior reduz explicitamente o rótulo obrigatório na seção de memória compartilhada
Importante
Isso é particularmente perigoso e o processo de maior integridade deve ter cuidado para validar todos os dados gravados na seção compartilhada.
Interfaces COM, em que os direitos de ativação de inicialização são definidos programaticamente pelo processo de maior integridade para permitir a associação de clientes de baixa integridade
Pipes nomeados, em que o criador define explicitamente o rótulo obrigatório no pipe para permitir o acesso a processos de integridade inferior
Esses mecanismos de comunicação permitem que o processo de baixa integridade interaja com outros processos de aplicativo, como um processo de agente, projetados especificamente para aceitar entradas ou chamadas da fonte de baixa integridade.
Uma diretriz geral para criar interfaces que um processo de baixa integridade chamará é nunca confiar no chamador ou nos dados de entrada. Um agente de integridade média pode fornecer uma interface para criar um arquivo dado um caminho e permitir que um aplicativo de baixa integridade chame a interface. No entanto, isso derrota a finalidade de executar um aplicativo com baixa integridade. Um design melhor é para um processo de baixa integridade chamar uma interface que solicita que o aplicativo de integridade média apresente uma caixa de diálogo de arquivo comum ao usuário, que o processo de baixa integridade não pode conduzir usando mensagens de janela. Dessa forma, você permite que o usuário navegue e selecione qual arquivo abrir ou criar, e o processo de integridade média faz todas as operações de arquivo. Esse tipo de cenário Salvar como é um exemplo de como a Internet do Modo Protegido Explorer usa seu próprio processo de agente para lidar com o salvamento de uma página da Web em algum lugar no perfil do usuário.
Muitos recursos de aplicativo podem ser executados corretamente em um processo de baixa integridade. Não há um conjunto comum de ferramentas para executar aplicativos com baixa integridade. Cada aplicativo é diferente e nem todos os aplicativos precisam ser executados com baixa integridade.