Ejemplo n.º 1
0
        private static void GetBranchTargetInjectionInformation(SpeculativeExecutionAssessment speculativeExecutionAssessment)
        {
            IntPtr systemInformationPtr = Marshal.AllocHGlobal(4);
            IntPtr returnLengthPtr      = Marshal.AllocHGlobal(4);

            try {
                uint systemInformationLength = 4;

                long retval = NtQuerySystemInformation(
                    SYSTEM_INFORMATION_CLASS.SystemBranchTargetInjection,
                    systemInformationPtr, systemInformationLength, returnLengthPtr);

                // ((retval == 0xC0000002) || (retval == 0xC0000003))
                // Windows hotfix not installed
                if ((retval != 0) && (retval != 0xC0000002) && (retval != 0xC0000003))
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    var message = $"Unexpected value returned from NtQuerySystemInformation: {retval}";
                    Console.WriteLine(message);
                    speculativeExecutionAssessment.ErrorMessage = message;
                    Console.ResetColor();
                    return;
                }
                else if (retval == 0)
                {
                    speculativeExecutionAssessment.SetBranchTargetInjectionProperties(systemInformationPtr);
                }
            }
            finally {
                if (systemInformationPtr != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(systemInformationPtr);
                }

                if (returnLengthPtr != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(returnLengthPtr);
                }
            }
        }
Ejemplo n.º 2
0
        static void Main(string[] args)
        {
            var speculativeExecutionAssessment = new SpeculativeExecutionAssessment();

            try {
                GetBranchTargetInjectionInformation(speculativeExecutionAssessment);
                if (string.IsNullOrWhiteSpace(speculativeExecutionAssessment.ErrorMessage))
                {
                    GetKernelVAShadowInformation(speculativeExecutionAssessment);
                }

                #region Display/log results and guidance
                if (string.IsNullOrWhiteSpace(speculativeExecutionAssessment.ErrorMessage))
                {
                    Console.ForegroundColor = ConsoleColor.Cyan;
                    Console.WriteLine("For more information about the output below, please refer to: https://support.microsoft.com/en-gb/help/4074629/understanding-the-output-of-get-speculationcontrolsettings-powershell");
                    Console.WriteLine();

                    #region Speculation control settings for CVE-2017-5715 [branch target injection]
                    Console.WriteLine("Speculation control settings for CVE-2017-5715 [branch target injection]");
                    Console.WriteLine();
                    Console.ResetColor();

                    #region Debug logging
                    Debug.WriteLine($"BpbEnabled: {speculativeExecutionAssessment.BTIFlags.HasFlag(BTIFlags.SCFBpbEnabled)}");
                    Debug.WriteLine($"BpbDisabledSystemPolicy: {speculativeExecutionAssessment.BTIFlags.HasFlag(BTIFlags.SCFBpbDisabledSystemPolicy)}");
                    Debug.WriteLine($"BpbDisabledNoHardwareSupport: {speculativeExecutionAssessment.BTIFlags.HasFlag(BTIFlags.SCFBpbDisabledNoHardwareSupport)}");
                    Debug.WriteLine($"HwReg1Enumerated: {speculativeExecutionAssessment.BTIFlags.HasFlag(BTIFlags.SCFHwReg1Enumerated)}");
                    Debug.WriteLine($"HwReg2Enumerated: {speculativeExecutionAssessment.BTIFlags.HasFlag(BTIFlags.SCFHwReg2Enumerated)}");
                    Debug.WriteLine($"HwMode1Present: {speculativeExecutionAssessment.BTIFlags.HasFlag(BTIFlags.SCFHwMode1Present)}");
                    Debug.WriteLine($"HwMode2Present: {speculativeExecutionAssessment.BTIFlags.HasFlag(BTIFlags.SCFHwMode2Present)}");
                    Debug.WriteLine($"SmepPresent: {speculativeExecutionAssessment.BTIFlags.HasFlag(BTIFlags.SCFHwMode2Present)}");
                    Debug.WriteLine($"SSBDAvailable: {speculativeExecutionAssessment.BTIFlags.HasFlag(BTIFlags.SCFSSBDAvailable)}");
                    Debug.WriteLine($"SSBDSupported: {speculativeExecutionAssessment.BTIFlags.HasFlag(BTIFlags.SCFSSBDSupported)}");
                    Debug.WriteLine($"SSBDSystemWide: {speculativeExecutionAssessment.BTIFlags.HasFlag(BTIFlags.SCFSSBDSystemWide)}");
                    Debug.WriteLine($"SSBDRequired: {speculativeExecutionAssessment.BTIFlags.HasFlag(BTIFlags.SCFSSBDRequired)}");
                    Debug.WriteLine($"SpecCtrlRetpolineEnabled: {speculativeExecutionAssessment.BTIFlags.HasFlag(BTIFlags.SCFSpecCtrlRetpolineEnabled)}");
                    Debug.WriteLine($"SCFSpecCtrlImportOptimizationEnabled: {speculativeExecutionAssessment.BTIFlags.HasFlag(BTIFlags.SCFSpecCtrlImportOptimizationEnabled)}");
                    #endregion

                    Console.Write("Hardware support for branch target injection mitigation is present: ");
                    Console.ForegroundColor = speculativeExecutionAssessment.BTIHardwarePresent
                        ? ConsoleColor.Green
                        : ConsoleColor.Red;
                    Console.WriteLine(speculativeExecutionAssessment.BTIHardwarePresent.ToString().ToUpperInvariant());
                    Console.ResetColor();

                    Console.Write("Windows OS support for branch target injection mitigation is present: ");
                    Console.ForegroundColor = speculativeExecutionAssessment.BTIWindowsSupportPresent
                        ? ConsoleColor.Green
                        : ConsoleColor.Red;
                    Console.WriteLine(speculativeExecutionAssessment.BTIWindowsSupportPresent.ToString().ToUpperInvariant());
                    Console.ResetColor();

                    Console.Write("Windows OS support for branch target injection mitigation is enabled: ");
                    Console.ForegroundColor = speculativeExecutionAssessment.BTIWindowsSupportEnabled
                        ? ConsoleColor.Green
                        : ConsoleColor.Red;
                    Console.WriteLine(speculativeExecutionAssessment.BTIWindowsSupportEnabled.ToString().ToUpperInvariant());
                    Console.ResetColor();

                    #region If Windows support for branch target injection mitigation is present but not enabled, log the reason (absence of settings or lack of hardware support)
                    if (speculativeExecutionAssessment.BTIWindowsSupportPresent && !speculativeExecutionAssessment.BTIWindowsSupportEnabled)
                    {
                        Console.Write($"Windows OS support for branch target injection mitigation is disabled by system policy: ");
                        Console.ForegroundColor = speculativeExecutionAssessment.BTIDisabledBySystemPolicy
                            ? ConsoleColor.Red
                            : ConsoleColor.Green;
                        Console.WriteLine(speculativeExecutionAssessment.BTIDisabledBySystemPolicy.ToString().ToUpperInvariant());
                        Console.ResetColor();

                        Console.Write($"Windows OS support for branch target injection mitigation is disabled by absence of hardware support: ");
                        Console.ForegroundColor = speculativeExecutionAssessment.BTIDisabledByNoHardwareSupport
                            ? ConsoleColor.Red :
                                                  ConsoleColor.Green;
                        Console.WriteLine(speculativeExecutionAssessment.BTIDisabledByNoHardwareSupport.ToString().ToUpperInvariant());
                        Console.ResetColor();
                    }
                    #endregion

                    #endregion

                    #region Speculation control settings for CVE-2017-5754 [rogue data cache load]
                    Console.ForegroundColor = ConsoleColor.Cyan;
                    Console.WriteLine();
                    Console.WriteLine("Speculation control settings for CVE-2017-5754 [rogue data cache load]");
                    Console.WriteLine();
                    Console.ResetColor();

                    #region Debug logging
                    Debug.WriteLine($"KVAShadowWindowsSupportEnabled: {speculativeExecutionAssessment.KVAShadowWindowsSupportEnabled.ToString().ToUpperInvariant()}");
                    Debug.WriteLine($"KvaShadowUserGlobal: {speculativeExecutionAssessment.KernelVAFlags.HasFlag(KernelVAFlags.KVAShadowUserGlobalFlag)}");
                    Debug.WriteLine($"KvaShadowPCID: {speculativeExecutionAssessment.KVAShadowPCIDEnabled.ToString().ToUpperInvariant()}");
                    Debug.WriteLine($"KvaShadowInvPCID: {speculativeExecutionAssessment.KernelVAFlags.HasFlag(KernelVAFlags.KVAShadowInvPCIDFlag)}");
                    Debug.WriteLine($"L1TFRequired: {speculativeExecutionAssessment.L1TFRequired.ToString().ToUpperInvariant()}");
                    Debug.WriteLine($"L1TFInvalidPTEBit: {(speculativeExecutionAssessment.L1TFInvalidPTEBit.HasValue ? speculativeExecutionAssessment.L1TFInvalidPTEBit.Value.ToString() : "UNKNOWN")}");
                    Debug.WriteLine($"L1TFFlushSupported: {speculativeExecutionAssessment.L1TFFlushSupported.ToString().ToUpperInvariant()}");
                    #endregion

                    Console.WriteLine($"Hardware requires kernel VA shadowing: {speculativeExecutionAssessment.KVAShadowRequired.ToString().ToUpperInvariant()}");

                    if (speculativeExecutionAssessment.KVAShadowRequired)
                    {
                        Console.Write("Windows OS support for kernel VA shadow is present: ");
                        Console.ForegroundColor = speculativeExecutionAssessment.KVAShadowWindowsSupportPresent
                            ? ConsoleColor.Green
                            : ConsoleColor.Red;
                        Console.WriteLine(speculativeExecutionAssessment.KVAShadowWindowsSupportPresent.ToString().ToUpperInvariant());
                        Console.ResetColor();

                        Console.Write("Windows OS support for kernel VA shadow is enabled: ");
                        Console.ForegroundColor = speculativeExecutionAssessment.KVAShadowWindowsSupportEnabled
                            ? ConsoleColor.Green
                            : ConsoleColor.Red;
                        Console.WriteLine(speculativeExecutionAssessment.KVAShadowWindowsSupportEnabled.ToString().ToUpperInvariant());
                        Console.ResetColor();

                        if (speculativeExecutionAssessment.KVAShadowWindowsSupportEnabled)
                        {
                            Console.Write("Windows OS support for PCID performance optimization is enabled [not required for security]: ");
                            Console.ForegroundColor = speculativeExecutionAssessment.KVAShadowPCIDEnabled
                                ? ConsoleColor.Green
                                : ConsoleColor.White;
                            Console.WriteLine(speculativeExecutionAssessment.KVAShadowPCIDEnabled.ToString().ToUpperInvariant());
                            Console.ResetColor();
                        }
                    }

                    #endregion

                    #region Speculation control settings for CVE-2018-3639 [speculative store bypass]
                    Console.ForegroundColor = ConsoleColor.Cyan;
                    Console.WriteLine();
                    Console.WriteLine("Speculation control settings for CVE-2018-3639 [speculative store bypass]");
                    Console.WriteLine();
                    Console.ResetColor();

                    Console.Write("Hardware is vulnerable to speculative store bypass: "******"UNKNOWN";
                    if (!speculativeExecutionAssessment.SSBDRequired.HasValue)
                    {
                        Console.ForegroundColor = ConsoleColor.Red;
                    }
                    Console.WriteLine(ssbdRequired);
                    Console.ResetColor();

                    if (speculativeExecutionAssessment.SSBDRequired.HasValue && speculativeExecutionAssessment.SSBDRequired.Value)
                    {
                        Console.Write("Hardware support for speculative store bypass mitigation is present: ");
                        Console.ForegroundColor = speculativeExecutionAssessment.SSBDHardwarePresent
                            ? ConsoleColor.Green
                            : ConsoleColor.Red;
                        Console.WriteLine(speculativeExecutionAssessment.SSBDHardwarePresent.ToString().ToUpperInvariant());
                        Console.ResetColor();

                        Console.Write("Windows OS support for speculative store bypass mitigation is present: ");
                        Console.ForegroundColor = speculativeExecutionAssessment.SSBDAvailable
                            ? ConsoleColor.Green
                            : ConsoleColor.Red;
                        Console.WriteLine(speculativeExecutionAssessment.SSBDAvailable.ToString().ToUpperInvariant());
                        Console.ResetColor();

                        Console.Write("Windows OS support for speculative store bypass mitigation is enabled system-wide: ");
                        Console.ForegroundColor = speculativeExecutionAssessment.SSBDSystemWide
                            ? ConsoleColor.Green
                            : ConsoleColor.Red;
                        Console.WriteLine(speculativeExecutionAssessment.SSBDSystemWide.ToString().ToUpperInvariant());
                        Console.ResetColor();
                    }

                    #endregion

                    #region Speculation control settings for CVE-2018-3620 [L1 terminal fault]
                    Console.ForegroundColor = ConsoleColor.Cyan;
                    Console.WriteLine();
                    Console.WriteLine("Speculation control settings for CVE-2018-3620 [L1 terminal fault]");
                    Console.WriteLine();
                    Console.ResetColor();

                    Console.WriteLine($"Hardware is vulnerable to L1 terminal fault: {speculativeExecutionAssessment.L1TFRequired.ToString().ToUpperInvariant()}");

                    if (speculativeExecutionAssessment.L1TFRequired)
                    {
                        Console.Write("Windows OS support for L1 terminal fault mitigation is present: ");
                        Console.ForegroundColor = speculativeExecutionAssessment.L1TFMitigationPresent
                            ? ConsoleColor.Green
                            : ConsoleColor.Red;
                        Console.WriteLine(speculativeExecutionAssessment.L1TFMitigationPresent.ToString().ToUpperInvariant());
                        Console.ResetColor();

                        Console.Write("Windows OS support for L1 terminal fault mitigation is enabled: ");
                        Console.ForegroundColor = speculativeExecutionAssessment.L1TFMitigationEnabled
                            ? ConsoleColor.Green
                            : ConsoleColor.Red;
                        Console.WriteLine(speculativeExecutionAssessment.L1TFMitigationEnabled.ToString().ToUpperInvariant());
                        Console.ResetColor();
                    }

                    #endregion

                    #region Speculation control settings for MDS [Microarchitectural Data Sampling]
                    Console.ForegroundColor = ConsoleColor.Cyan;
                    Console.WriteLine();
                    Console.WriteLine("Speculation control settings for MDS [Microarchitectural Data Sampling]");
                    Console.WriteLine();
                    Console.ResetColor();

                    Console.WriteLine($"Windows OS support for MDS mitigation is present: {speculativeExecutionAssessment.MDSMBClearReported.ToString().ToUpperInvariant()}");

                    if (speculativeExecutionAssessment.MDSMBClearReported)
                    {
                        Console.Write("Hardware is vulnerable to MDS: ");
                        Console.ForegroundColor = ConsoleColor.White;
                        Console.WriteLine((!speculativeExecutionAssessment.MDSHardwareProtected).ToString().ToUpperInvariant());
                        Console.ResetColor();

                        if (!speculativeExecutionAssessment.MDSHardwareProtected)
                        {
                            Console.Write("Windows OS support for MDS mitigation is enabled: ");
                            Console.ForegroundColor = speculativeExecutionAssessment.MDSMBClearEnabled
                                ? ConsoleColor.Green
                                : ConsoleColor.Red;
                            Console.WriteLine(speculativeExecutionAssessment.MDSMBClearEnabled.ToString().ToUpperInvariant());
                            Console.ResetColor();
                        }
                    }

                    #endregion

                    var actions = new List <string>();
                    if (!speculativeExecutionAssessment.BTIHardwarePresent)
                    {
                        actions.Add("Install BIOS/firmware update provided by your device OEM that enables hardware support for the branch target injection mitigation.");
                    }

                    if (!speculativeExecutionAssessment.BTIWindowsSupportPresent ||
                        !speculativeExecutionAssessment.KVAShadowWindowsSupportPresent ||
                        !speculativeExecutionAssessment.SSBDAvailable ||
                        !speculativeExecutionAssessment.L1TFMitigationPresent)
                    {
                        actions.Add("Install the latest available updates for Windows with support for speculation control mitigations.");
                    }

                    if ((speculativeExecutionAssessment.BTIHardwarePresent &&
                         !speculativeExecutionAssessment.BTIWindowsSupportEnabled) ||
                        (speculativeExecutionAssessment.KVAShadowRequired &&
                         !speculativeExecutionAssessment.KVAShadowWindowsSupportEnabled) ||
                        (speculativeExecutionAssessment.L1TFRequired &&
                         !speculativeExecutionAssessment.L1TFMitigationPresent))
                    {
                        var guidanceUri  = string.Empty;
                        var guidanceType = string.Empty;

                        var productTypeWmiErrorMessage = GetWindowsProductTypeWmiInformation(out int productType);
                        if (string.IsNullOrWhiteSpace(productTypeWmiErrorMessage) && productType > 0)
                        {
                            if (productType == 1)
                            {
                                guidanceUri  = "https://support.microsoft.com/help/4073119";
                                guidanceType = "Client";
                            }
                            else
                            {
                                guidanceUri  = "https://support.microsoft.com/help/4072698";
                                guidanceType = "Server";
                            }

                            actions.Add($"Follow the guidance for enabling Windows {guidanceType} support for speculation control mitigations described in: {guidanceUri}");
                        }
                        else
                        {
                            speculativeExecutionAssessment.ErrorMessage = productTypeWmiErrorMessage;
                        }
                    }

                    if (actions.Count > 0)
                    {
                        Console.ForegroundColor = ConsoleColor.Cyan;
                        Console.WriteLine();
                        Console.WriteLine("Suggested actions:");
                        Console.WriteLine();
                        foreach (var item in actions)
                        {
                            Console.WriteLine(item);
                        }
                        Console.ResetColor();
                    }
                }
                #endregion
            }
            catch (Exception e) {
                speculativeExecutionAssessment.ErrorMessage = e.Message;
            }

            CreateReport(args, speculativeExecutionAssessment);
            Console.WriteLine("Done.");
        }
Ejemplo n.º 3
0
        private static void CreateReport(string[] args, SpeculativeExecutionAssessment speculativeExecutionAssessment)
        {
            if (speculativeExecutionAssessment == null)
            {
                throw new ArgumentNullException(nameof(speculativeExecutionAssessment));
            }

            var reportFolder = string.Empty;

            if (args.Any(x => x.StartsWith("/ReportFolder:", StringComparison.OrdinalIgnoreCase)))
            {
                try {
                    reportFolder = args
                                   .Where(x => x.StartsWith("/ReportFolder:", StringComparison.OrdinalIgnoreCase))
                                   .FirstOrDefault();

                    if (!string.IsNullOrWhiteSpace(reportFolder))
                    {
                        reportFolder = reportFolder.Substring("/ReportFolder:".Length);
                    }
                    if (!string.IsNullOrWhiteSpace(reportFolder))
                    {
                        if (!Directory.Exists(reportFolder))
                        {
                            Directory.CreateDirectory(reportFolder);
                        }
                    }
                }
                catch (Exception e) {
                    Console.WriteLine($"Error parsing reportFolder argument: {e.VerboseExceptionString()}");
                }

                if (string.IsNullOrWhiteSpace(reportFolder))
                {
                    reportFolder = AppDomain.CurrentDomain.BaseDirectory;
                }
            }

            var xmlReportFilePath = Path.Combine(reportFolder, $"{Environment.MachineName}_SpeculativeExecutionAssessment.xml");

            Console.WriteLine();
            Console.Write($"Creating assessment report file: {xmlReportFilePath}.");
            using (var fileStream = new FileStream(xmlReportFilePath, FileMode.Create))
                using (var streamWriter = new StreamWriter(fileStream, Encoding.UTF8)) {
                    var xmlSerializer = new XmlSerializer(typeof(SpeculativeExecutionAssessment));
                    xmlSerializer.Serialize(streamWriter, speculativeExecutionAssessment);
                }

            var xmlString = new StringBuilder();

            using (var stringWriter = new StringWriter(xmlString)) {
                var xmlSerializer = new XmlSerializer(typeof(SpeculativeExecutionAssessment));
                xmlSerializer.Serialize(stringWriter, speculativeExecutionAssessment);
                using (var registryKey = Registry.LocalMachine.OpenSubKey(
                           @"Software\Microsoft\Windows\CurrentVersion\", writable: true)) {
                    if (registryKey != null)
                    {
                        var speculationControlRegistryKey = registryKey.OpenSubKey("SpeculationControl", writable: true);
                        if (speculationControlRegistryKey == null)
                        {
                            speculationControlRegistryKey = registryKey.CreateSubKey("SpeculationControl", writable: true);
                        }
                        speculationControlRegistryKey.SetValue("SpeculativeExecutionAssessment", xmlString.ToString(), RegistryValueKind.String);
                        speculationControlRegistryKey.Dispose();
                    }
                }
            }

            var csvReportFilePath = Path.Combine(reportFolder, $"{Environment.MachineName}_SpeculativeExecutionAssessment.csv");

            Console.WriteLine();
            Console.Write($"Creating assessment report file: {csvReportFilePath}.");

            var csvReportLines = new List <string> {
                SpeculativeExecutionAssessment.CSVHeader
            };

            csvReportLines.Add(speculativeExecutionAssessment.ToCSVString());
            File.WriteAllLines(csvReportFilePath, csvReportLines);

            Console.WriteLine("Done.");
        }