Report quality definitions for Microsoft’s Bug Bounty programs 

Microsoft strives to address reported vulnerabilities as quickly as possible. One of the factors that influences the time to address a vulnerability is how long it takes to assess the root cause, severity, and impact of the vulnerability. In practice, the amount of time it takes Microsoft to assess a vulnerability is heavily influenced by the quality of the information provided with a vulnerability report.

To help security researchers better understand the information we need to accelerate the assessment of a vulnerability, we’ve defined three quality levels for a vulnerability report: low, medium, and high. These quality levels are summarized in the table below. We encourage everyone to provide high quality reports whenever possible and our bounty programs typically incentivize this by offering higher rewards for higher quality reports. 

While we prefer high quality reports, we always want to learn about vulnerabilities that affect Microsoft, so we encourage researchers to report vulnerabilities even if they are not able to provide the highest level of quality. 

 

Quality

Description

Information Required

Low

A low quality vulnerability report provides sufficient information to reproduce the vulnerability but does not include a reliable proof of concept.

  • Type of vulnerability
  • Affected component (name, version)
  • Affected target environment (type, version)
  • Vulnerability reproduction output (debugger output, screenshot, etc)
  • Proof-of-concept

Medium

A medium quality vulnerability report improves upon a low quality report by providing a proof of concept that is reliable and minimized.

  • All information required by a low quality report
  • Reliable & minimized proof-of-concept

High

A high quality vulnerability report improves upon a medium quality report by providing a detailed and correct analysis of the vulnerability.

  • All information required by a medium quality report
  • Detailed & correct analysis
Explanation of information required

Information

Explantion

Type of vulnerability 

A classification of the type of vulnerability being reported, such as Use After Free, Cross-Site Scripting, and so on. For examples of vulnerability types, it may be helpful to refer to https://nvd.nist.gov/vuln/categories

Affected Component

The component or service that is affected by the vulnerability. This should include the component’s name and any relevant version information. 

Affected target environment

The target environment that is affected by the vulnerability, such as the operating system or application that is affected. This should include a description of the target environment, including its name and any relevant version information.  

 

For Windows targets, this should include the BuildLabEx string which can be found here: 

 

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

Vulnerability reproduction output 

The output from a successful reproduction of the vulnerability. This could consist of debugger output, a screenshot, a video, or some other format that demonstrates a reproduction of the issue. More detailed information like debugger output is preferred. 

Proof-of-concept

A description of the vulnerability in the form of text, code, or other form depending on the nature of the vulnerability. This description should include all steps required to trigger the vulnerability. Any information about how the target needs to be configured to trigger the vulnerability should also be included.

Reliable & minimized proof-of-concept 

A proof-of-concept that reproduces the vulnerability automatically (e.g. with code) when applicable. This proof-of-concept should:

 

  • Work with minimal or no system modifications
  • Be minimized; there should be no redundant or irrelevant instructions
  • Reproduce reliably within a reasonable period of time

Detailed & correct analysis

This analysis should correctly describe how each part of the proof-of-concept affects the target in terms of triggering the vulnerability. In addition, the analysis should include information about how timing, environment, or other constraints affect successfully triggering the vulnerability. This analysis should also describe the root cause of the vulnerability, to the degree possible.

High Quality Report Example

Windows:
Sandboxed Mount Reparse Point Creation Mitigation Bypass
Platform:
Windows 10 (build 10240), earlier versions do not have the functionality
Class:
Security Feature Bypass
Bounty Program:
Mitigation Bypass Bounty Program
Summary:
A mitigation added to Windows 10 to prevent NTFS Mount Reparse Points being created at integrity levels below medium can be bypassed.
Description:
Windows 10 has added some new mitigations to block the creation or change the behaviour of certain symbolic links when issued by a low integrity/sandboxed process. The presumed aim to make it harder to abuse these types of tricks to break out of a sandbox.
 
In earlier builds on Windows 10 NTFS Mount Reparse Points were blocked outright from a sandboxed process, however in 10240 (what can only be assumed a final build) the check was moved to the kernel in IopXXXControlFile and changed slightly so that sandboxed processes could create some mount points. The check is roughly:
 
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; 
       } 
   } 
}
 
The kernel is therefore checking that the target of the mount point is a directory and that the current process has write access to the directory. This would sufficiently limit the ability of a sandboxed process to abuse this to write files at a higher privilege. Unfortunately there’s a perhaps unexpected problem with this check, the sandboxed process can redirect the ZwOpenFile call arbitrarily to something it can open for write, yet the original value is set as the mount point. This is because the file open check is being made inside the process which is doing the call which means it honours the user’s device mapping.
 
While the sandboxed process cannot change the per-user drive mappings, it can change the process’s device map using NtSetInformationProcess with the ProcessDeviceMap information class. As we can create arbitrary object directories and symbolic links (which while they also have a mitigation it only prevents a higher privilege process following them, which we don’t care about) we can build a completely fake device map which redirects the open to another directory. A good target turns out to be \Device\NamedPipe\ (note the trailing slash) as that can be opened from any privilege level (including Chrome renderer processes) for write access and as a directory. So if we want to set an arbitrary mount point to say \??\c:\somewhere we can build something like:
 
<UNNAMED>(DIR) -> C:(DIR) -> somewhere(LINK to \Device\NamedPipe\)
 
If we set the unnamed directory to the process device map we can bypass the check and create the mount point.
 
Perhaps from a fix perspective you could query for the opened path and use that to write to the NTFS reparse point rather than using the original value.
 
Proof of Concept:
I’ve provided a PoC which will demonstrate the bypass. It should be executed at low integrity using psexec or modifying the executable file’s ACL to low. Ensure you use the correct version for the architecture on Windows, as there seems to be a bug in NtSetInformationProcess which blocks Wow64 apps from setting the process device map. You can compare the operation to the command shell’s mklink tool that will fail to create the mount point at low integrity. Follow these steps:
 
1) Extract the PoC to a location on a local hard disk which is writable by a normal user.
 
2) Execute the poc executable file as low integrity passing two arguments, the path to a directory to create (must be somewhere than can be written to as low integrity user such as AppData\Temp\Low) and the arbitrary file path to set the mount point to. For example:

poc.exe c:\users\user\appdata\local\low\abc c:\notreal.
 
Expected Result:
It shouldn’t be possible to create a mount point pointed at a location not writable by low integrity user
 
Observed Result:
The mount point is created successfully.
 
Special thanks to James Forshaw for his consistent, high-quality submissions to the Microsoft Security Response Center.
 
 

Low Quality Report Example

 

# 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" 
} 
```