Definições de qualidade de relatório para os Programas de Recompensas por Localização de Bug da Microsoft 

A Microsoft se esforça para tratar das vulnerabilidades relatadas o mais rápido possível. Um dos fatores que influenciam o tempo necessário para tratar de uma vulnerabilidade é quanto tempo leva para avaliar sua causa raiz, severidade e impacto. Na prática, o tempo necessário para a Microsoft avaliar uma vulnerabilidade é muito influenciado pela qualidade das informações fornecidas com o relatório de vulnerabilidade.

Para ajudar os pesquisadores de segurança a entender melhor as informações de que precisamos para acelerar a avaliação de uma vulnerabilidade, definimos três níveis de qualidade para os relatórios de vulnerabilidade: baixo, médio e alto. Esses níveis de qualidade estão resumidos na tabela a seguir. Incentivamos todos a fornecerem relatórios de alta qualidade sempre que possível e nossos programas de recompensas geralmente incentivam isso oferecendo recompensas mais altas para relatórios de maior qualidade. 

Embora tenhamos preferência por relatórios de alta qualidade, sempre queremos saber sobre vulnerabilidades que afetam a Microsoft, de forma que incentivamos os pesquisadores a relatarem vulnerabilidades mesmo que não possam fazer isso com nível mais alto de qualidade. 

 

Qualidade

Descrição

Informações necessárias

Baixo

Um relatório de vulnerabilidade de baixa qualidade fornece informações suficientes para reproduzir a vulnerabilidade, mas não inclui uma prova de conceito confiável.

  • Tipo de vulnerabilidade
  • Componente afetado (nome, versão)
  • Ambiente de destino afetado (tipo, versão)
  • Saída da reprodução da vulnerabilidade (saída do depurador, captura de tela, etc)
  • Prova de conceito

Média

Um relatório de vulnerabilidade de qualidade média aprimora o relatório de baixa qualidade fornecendo uma prova de conceito confiável e minimizada.

  • Todas as informações exigidas por um relatório de baixa qualidade
  • Prova de conceito confiável e minimizada

Alto

Um relatório de vulnerabilidade de alta qualidade aprimora o relatório de qualidade média fornecendo uma análise detalhada e correta da vulnerabilidade.

  • Todas as informações exigidas por um relatório de média qualidade
  • Análise detalhada e correta
Explanation of information required

Informações

Explicação

Tipo de vulnerabilidade 

Uma classificação do tipo de vulnerabilidade sendo relatada, como Use After Free, Cross-Site Scripting e assim por diante. Para ver exemplos de tipos de vulnerabilidade, pode ser útil consultar https://nvd.nist.gov/vuln/categories

Componente afetado

O componente ou serviço afetado pela vulnerabilidade. Deve incluir o nome do componente e todas as informações de versão relevantes. 

Ambiente de destino afetado

O ambiente de destino que é afetado pela vulnerabilidade, como o sistema operacional ou o aplicativo afetado. Deve incluir uma descrição do ambiente de destino, incluindo seu nome e as informações de versão relevantes. 

 

Para destinos do Windows, deve incluir a cadeia de caracteres BuildLabEx, que pode ser encontrada aqui: 

 

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\BuildLabEx 

Saída da reprodução da vulnerabilidade 

A saída de uma reprodução bem-sucedida da vulnerabilidade. Pode ser composta pela saída do depurador, uma captura de tela, um vídeo ou algum outro formato que demonstre uma reprodução do problema. Informações mais detalhadas, como a saída do depurador, são preferenciais. 

Prova de conceito

Uma descrição da vulnerabilidade na forma de texto, código ou em outra forma, dependendo da natureza da vulnerabilidade. Essa descrição deve incluir todas as etapas necessárias para disparar a vulnerabilidade. Informações sobre como o destino precisa ser configurado para disparar a vulnerabilidade também devem ser incluídas.

Prova de conceito confiável e minimizada 

Uma prova de conceito que reproduz a vulnerabilidade automaticamente (por exemplo, com código) quando aplicável. Essa prova de conceito deve:

 

  • Funcionar com poucas ou nenhuma modificação no sistema
  • Ser minimizada; não deve haver instruções redundantes ou irrelevantes
  • Ser reproduzida de forma confiável em um período razoável

Análise detalhada e correta

Essa análise deve descrever corretamente como cada parte da prova de conceito afeta o destino em termos de disparar a vulnerabilidade. Além disso, a análise deve incluir informações sobre como o tempo, o ambiente ou outras restrições afetam com êxito a vulnerabilidade. A análise ainda deve descrever a causa raiz da vulnerabilidade tanto quanto possível.

Exemplo de relatório de alta qualidade

Windows:
Bypass da mitigação de criação de ponto de nova análise de montagem em área restrita
Plataforma:
Windows 10 (build 10240) (versões anteriores não têm a funcionalidade)
Classe:
Bypass de recurso de segurança
Programa de Recompensas:
Programa de Recompensas de Bypass de Mitigação
Resumo:
uma mitigação adicionada ao Windows 10 para impedir que pontos de nova análise de montagem do NTFS sejam criados nos níveis de integridade abaixo de médio pode ser ignorada.
Descrição:
o Windows 10 adicionou algumas novas mitigações para bloquear a criação ou alterar o comportamento de determinados links simbólicos quando emitidos por um processo de baixa integridade/área restrita. O objetivo presumido é dificultar o abuso desses tipos de truques para sair de uma área restrita.
 
Em builds anteriores do Windows 10, os pontos de nova análise de montagem do NTFS eram bloqueados diretamente de um processo na área restrita. No entanto, no 10240 (que só pode ser considerado um build final), a verificação foi movida para o kernel em IopXXXControlFile e mudou ligeiramente para que os processos em área restrita pudessem criar alguns pontos de montagem. A verificação é, aproximadamente:
 
if (RtlIsSandboxedProcess()) { 
   if(ControlCode == FSCTL_SET_MOUNT_POINT) { 
       if (FsRtlValidateReparsePointBuffer(buffer) && buffer->ReparseTag == TAG_MOUNT_POINT) { 
         NTSTATUS status = ZwOpenFile(..., buffer->ReparseTarget, FILE_GENERIC_WRITE, ... , FILE_DIRECTORY_FILE); 
        if (!NT_SUCCESS(status)) { 
         return status; 
       } 
   } 
}
 
Portanto, o kernel está verificando se o destino do ponto de montagem é um diretório e se o processo atual tem acesso de gravação ao diretório. Isso limitaria suficientemente a capacidade de um processo em área restrita de abusar disso para gravar arquivos com um privilégio maior. Infelizmente, há um problema possivelmente inesperado com essa verificação: o processo em área restrita pode redirecionar a chamada ZwOpenFile de modo arbitrário para algo que ele pode abrir para gravação, mas o valor original fica definido como o ponto de montagem. Isso ocorre porque a verificação de abertura de arquivo está sendo feita dentro do processo que está fazendo a chamada, o que significa que ela respeita o mapeamento do dispositivo do usuário.
 
Embora o processo em área restrita não possa alterar os mapeamentos de unidade por usuário, ele pode alterar o mapa do dispositivo do processo usando NtSetInformationProcess com a classe de informações ProcessDeviceMap. Como podemos criar diretórios de objetos arbitrários e links simbólicos (o que, embora também tenha uma mitigação, só impede que um processo com privilégio mais alto o siga, não é uma preocupação para nós), podemos criar um mapa de dispositivo completamente falso que redireciona a abertura para outro diretório. Um bom destino acaba sendo \Device\NamedPipe\ (observe a barra à direita), já que ele pode ser aberto com qualquer nível de privilégio (incluindo os processos do renderizador do Chrome) para acesso de gravação e como um diretório. Então, se quisermos definir um ponto de montagem arbitrário como \??\c:\somewhere, poderemos criar algo como:
 
<UNNAMED>(DIR) -> C:(DIR) -> somewhere(LINK to \Device\NamedPipe\)
 
Se definirmos o diretório sem nome para o mapa do dispositivo do processo, poderemos ignorar a verificação e criar o ponto de montagem.
 
Talvez, de uma perspectiva de correção, você pudesse consultar o caminho aberto e usá-lo para gravar no ponto de nova análise do NTFS em vez de usar o valor original.
 
Prova de conceito:
Forneci uma prova de conceito que demonstrará o bypass. Ela deve ser executada com baixa integridade usando psexec ou modificando o ACL do arquivo executável para baixo. Certifique-se de usar a versão correta para a arquitetura no Windows, pois parece haver um bug em NtSetInformationProcess que impede que aplicativos Wow64 definam o mapa do dispositivo de processo. Você pode comparar a operação com a ferramenta mklink do shell de comando, que falhará na criação do ponto de montagem com baixa integridade. Siga estas etapas:
 
1) Extraia a PoC para uma localização em um disco rígido local que seja gravável por um usuário normal.
 
2) Execute o arquivo executável da PoC com baixa integridade passando dois argumentos, o caminho para um diretório a ser criado (deve ser um lugar que possa ser gravado por usuário com baixa integridade, como AppData\Temp\Low) e o caminho de arquivo arbitrário para o qual definir o ponto de montagem. Por exemplo:

poc.exe c:\users\user\appdata\local\low\abc c:\notreal.
 
Resultado esperado:
não deve ser possível criar um ponto de montagem apontado para uma localização não gravável por um usuário com baixa integridade
 
Resultado observado:
o ponto de montagem foi criado com êxito.
 
Um agradecimento especial a James Forshaw por seus envios consistentes e de alta qualidade para o Microsoft Security Response Center.
 
 

Exemplo de relatório de baixa qualidade

 

# win32kfull!NtGdiHLSurfGetInformation+0x11f kernel info leak 

## root cause 
the local kernel stack var KernerStackStuctVar is uninitialized. 
and direcly copy to usermode after call _GreSfmGetDirtyRgn@40. 
```cpp 
.text:0008718A ; int __stdcall NtGdiHLSurfGetInformation(int, int, void *, int) 
.text:0008718A public _NtGdiHLSurfGetInformation@16 
.text:0008718A _NtGdiHLSurfGetInformation@16 proc near 
.text:0008718A 
.text:0008718A KernerStackStuctVar = dword ptr -58h 
``` 
```cpp 
.text:0008729E push edi ; size_t 
.text:0008729F lea ecx, [ebp+KernerStackStuctVar] 
.text:000872A2 push ecx ; void * 
.text:000872A3 push eax ; void * 
.text:000872A4 call _memcpy ; xxxx 
``` 
```cpp 
"t": "ob", 
"v": { 
"pid": { 
"t": "nb", 
"v": 1044 
}, 
"tid": { 
"t": "nb", 
"v": 1108 
}, 
"imageName": { 
"t": "st", 
"v": "dwm.exe" 
}, 
"count": { 
"t": "nb", 
"v": 2 
}, 
"from": { 
"t": "st", 
"v": "NtGdiHLSurfGetInformation" 
}, 
"eip": { 
"t": "st", 
"v": "nt!memcpy+0x33" 
}, 
"data": { 
"t": "ob", 
"v": { 
"value": { 
"t": "n4", 
"s": false, 
"v": "0xaaaaaaaa" 
}, 
"type": { 
"t": "nu" 
} 
} 
}, 
"address": { 
"t": "n4", 
"s": false, 
"v": "0x36ef25c" 
}, 
"stacks": { 
"t": "ar", 
"v": [ 
{ 
"t": "st", 
"v": "win32kfull!NtGdiHLSurfGetInformation+0x11f" 
}, 
{ 
"t": "st", 
"v": "nt!KiSystemServicePostCall" 
}, 
{ 
"t": "nu" 
}, 
{ 
"t": "nu" 
} 
```