Modern malware is getting more and more sophisticated. Some of them, specifically bootkits, are capable of starting before Windows. Device Health Attestation can be used to detect and remediate in the unlikely event where a device is infected. The device's firmware logs the boot process, and Windows can send it to a trusted Health Attestation Server that can objectively assess the device's health. See Device Health Attestation architecture for more details.
Before this functionality can be used, additional Azure resources need to be deployed. See the deployment page for more details.
The Device Health Attestation functionality allows the operator to perform the following tasks:
- Schedule health attestation
- Initiate immediate health attestation
- Retrieve health attestation status
- Retrieve health attestation report
- Take remedial actions
The Schedule health attestation operation is initiated by the device receiving the "desired.windows.deviceHealthAttestation"
desired property.
The format of the "desired.windows.deviceHealthAttestation"
desired property is as follows:
"desired" : { "windows" : { "deviceHealthAttestation" :{ "Endpoint" : "see below" "ReportIntervalInSeconds" : "see below" } } }
"Endpoint"
: Health Attestation Server URI. When set to an empty string, the default Microsoft Health Attestation Server will be used. See this page on how to setup a custom Health Attestation Server."ReportIntervalInSeconds"
: Interval in seconds to perform health attestation. When set to"0"
, health attestation will be performed only once during startup. When set to"-1"
, health attestation will be disabled.
Examples
Perform a health attestation every hour against the default Microsoft Health Attestation Server, has.spserv.microsoft.com
:
"desired" : {
"windows" : {
"deviceHealthAttestation" : {
"Endpoint" : "has.spserv.microsoft.com"
"ReportIntervalInSeconds" : "3600"
}
}
}
After the device attests, the "reported.windows.deviceHealthAttestation.status"
property is set, which is defined as follows:
"reported" : { "windows" : { "deviceHealthAttestation" : { "status": "Status of last health attestation", "TimeStamp": "Datetime in ISO 8601 format, UTC" } } }
The Immediate Health Attestation operation is initiated by the device receiving the windows.deviceHealthAttestationReportNow
method.
Input payload is empty
The device responds immediately with the following JSON payload:
"response" : "see below" "reason" : "see below"
"response"
: This can either be set to"accepted"
or"rejected"
. In case it is set to"rejected"
, the"reason"
field will contain more details on why the method has been rejected.."reason"
: If the"response"
is"accepted"
, this will be empty - otherwise, this field will contain more details on why the method has been rejected.
The state of the latest request is communicated to the back-end via reported properties as described in Retrieve Health Attestation Status.
Examples:
Successful response:
{
"response" : "accepted"
"reason" : ""
}
After the device attested successfully, a health report is generated. This report is stored in the Azure storage table, dhaReportTable
. Each row represent a single health report. The rowkey
is generated using the format <device name>-<timestamp of report>
. For example, DHA-client-2017-06-03T00:25:38.0240880Z
. This table can be accessed via GUI using Azure Storage Explorer or programmatically through Azure table storage APIs.
Here is a screen shot of a sample report viewed through the Azure Storage Explorer.
Please, see Device HealthAttestation CSP for more details about each field.
After a health report has been generated, the operator can optionally take remedial actions if the device's health is not compliant.
For example, the operator can perform a "factory reset" to bring the device back to a known state.
public async Task ProcessHealthReportAsync(HealthReport report)
{
if (!IsDeviceCompliance(report))
{
await FactoryResetAsync(report.DeviceId);
}
}
private bool IsDeviceCompliance(HealthReport report)
{
// Ensure secure boot is enabled.
bool secureBootEnabled;
if (!bool.TryParse(report.HealthCertificateProperties["SecureBootEnabled"], out secureBootEnabled))
{
return false;
}
return secureBootEnabled;
}
private async Task FactoryResetAsync(string deviceId)
{
// Invoke device method
dynamic param = new {
recoveryPartitionGUID = "<your recovery partition GUID>",
clearTPM = false
};
var json = JsonConvert.SerializeObject(param);
var cloudToDeviceMethod = new CloudToDeviceMethod("windows.factoryReset");
cloudToDeviceMethod.SetPayloadJson(json);
var result = await _iotHubServiceClient.InvokeDeviceMethodAsync(deviceId, cloudToDeviceMethod);
_log.Info($"FactoryResetAsync status: {result.Status}");
}
See HealthInspector sample code for details.