Vulnerabilities > CVE-2017-0007 - Improper Input Validation vulnerability in Microsoft Windows 10 and Windows Server 2016

047910
CVSS 5.5 - MEDIUM
Attack vector
LOCAL
Attack complexity
LOW
Privileges required
LOW
Confidentiality impact
NONE
Integrity impact
HIGH
Availability impact
NONE
local
low complexity
microsoft
CWE-20
nessus

Summary

Device Guard in Microsoft Windows 10 Gold, 1511, 1607, and Windows Server 2016 allows remote attackers to modify PowerShell script without invalidating associated signatures, aka "PowerShell Security Feature Bypass Vulnerability."

Common Weakness Enumeration (CWE)

Common Attack Pattern Enumeration and Classification (CAPEC)

  • Buffer Overflow via Environment Variables
    This attack pattern involves causing a buffer overflow through manipulation of environment variables. Once the attacker finds that they can modify an environment variable, they may try to overflow associated buffers. This attack leverages implicit trust often placed in environment variables.
  • Server Side Include (SSI) Injection
    An attacker can use Server Side Include (SSI) Injection to send code to a web application that then gets executed by the web server. Doing so enables the attacker to achieve similar results to Cross Site Scripting, viz., arbitrary code execution and information disclosure, albeit on a more limited scale, since the SSI directives are nowhere near as powerful as a full-fledged scripting language. Nonetheless, the attacker can conveniently gain access to sensitive files, such as password files, and execute shell commands.
  • Cross Zone Scripting
    An attacker is able to cause a victim to load content into their web-browser that bypasses security zone controls and gain access to increased privileges to execute scripting code or other web objects such as unsigned ActiveX controls or applets. This is a privilege elevation attack targeted at zone-based web-browser security. In a zone-based model, pages belong to one of a set of zones corresponding to the level of privilege assigned to that page. Pages in an untrusted zone would have a lesser level of access to the system and/or be restricted in the types of executable content it was allowed to invoke. In a cross-zone scripting attack, a page that should be assigned to a less privileged zone is granted the privileges of a more trusted zone. This can be accomplished by exploiting bugs in the browser, exploiting incorrect configuration in the zone controls, through a cross-site scripting attack that causes the attackers' content to be treated as coming from a more trusted page, or by leveraging some piece of system functionality that is accessible from both the trusted and less trusted zone. This attack differs from "Restful Privilege Escalation" in that the latter correlates to the inadequate securing of RESTful access methods (such as HTTP DELETE) on the server, while cross-zone scripting attacks the concept of security zones as implemented by a browser.
  • Cross Site Scripting through Log Files
    An attacker may leverage a system weakness where logs are susceptible to log injection to insert scripts into the system's logs. If these logs are later viewed by an administrator through a thin administrative interface and the log data is not properly HTML encoded before being written to the page, the attackers' scripts stored in the log will be executed in the administrative interface with potentially serious consequences. This attack pattern is really a combination of two other attack patterns: log injection and stored cross site scripting.
  • Command Line Execution through SQL Injection
    An attacker uses standard SQL injection methods to inject data into the command line for execution. This could be done directly through misuse of directives such as MSSQL_xp_cmdshell or indirectly through injection of data into the database that would be interpreted as shell commands. Sometime later, an unscrupulous backend application (or could be part of the functionality of the same application) fetches the injected data stored in the database and uses this data as command line arguments without performing proper validation. The malicious data escapes that data plane by spawning new commands to be executed on the host.

Msbulletin

bulletin_idMS17-012
bulletin_url
date2017-03-14T00:00:00
impactRemote Code Execution
knowledgebase_id4013078
knowledgebase_url
severityCritical
titleSecurity Update for Microsoft Windows

Nessus

NASL familyWindows : Microsoft Bulletins
NASL idSMB_NT_MS17-012.NASL
descriptionThe remote Windows host is missing a security update. It is, therefore, affected by multiple vulnerabilities : - A security feature bypass vulnerability exists in Device Guard due to improper validation of certain elements in a signed PowerShell script. An unauthenticated, remote attacker can exploit this vulnerability to modify the contents of a PowerShell script without invalidating the signature associated with the file, allowing the execution of a malicious script. (CVE-2017-0007) - A denial of service vulnerability exists in the Microsoft Server Message Block 2.0 and 3.0 (SMBv2/SMBv3) client implementations due to improper handling of certain requests sent to the client. An unauthenticated, remote attacker can exploit this issue, via a malicious SMB server, to cause the system to stop responding until it is manually restarted. (CVE-2017-0016) - A remote code execution vulnerability exists due to using an insecure path to load certain dynamic link library (DLL) files. A local attacker can exploit this, via a specially crafted library placed in the path, to execute arbitrary code. (CVE-2017-0039) - An information disclosure vulnerability exists in Windows dnsclient due to improper handling of certain requests. An unauthenticated, remote attacker can exploit this, by convincing a user to visit a specially crafted web page, to gain access to sensitive information on a targeted workstation. If the target is a server, the attacker can also exploit this issue by tricking the server into sending a DNS query to a malicious DNS server. (CVE-2017-0057) - An elevation of privilege vulnerability exists in Helppane.exe due to a failure by an unspecified DCOM object, configured to run as the interactive user, to properly authenticate the client. An authenticated, remote attacker can exploit this, via a specially crafted application, to execute arbitrary code in another user
last seen2020-06-01
modified2020-06-02
plugin id97743
published2017-03-15
reporterThis script is Copyright (C) 2017-2019 and is owned by Tenable, Inc. or an Affiliate thereof.
sourcehttps://www.tenable.com/plugins/nessus/97743
titleMS17-012: Security Update for Microsoft Windows (4013078)

Seebug

bulletinFamilyexploit
descriptionOver the past few months, I have had the pleasure to work side-by-side with Matt Graeber ([@mattifestation](https://twitter.com/mattifestation)) and Casey Smith ([@subtee](https://twitter.com/subtee)) in their previous job roles, researching Device Guard user mode code integrity (UMCI) bypasses. If you aren't familiar with Device Guard, you can read more about it here: [https://technet.microsoft.com/en-us/itpro/windows/keep-secure/device-guard-deployment-guide](https://technet.microsoft.com/en-us/itpro/windows/keep-secure/device-guard-deployment-guide). In short, Device Guard UMCI prevents unapproved binaries from executing, restricts the Windows Scripting Host, and it places PowerShell in [Constrained Language mode](https://technet.microsoft.com/en-us/library/dn433292.aspx), unless the scripts themselves are signed by a trusted signer. After spending some time evaluating how scripts are handled on Device Guard enabled systems, I ended up identifying a way to get any unapproved script to execute on a Device Guard enabled system. Upon reporting the issue to MSRC, this bug was eventually assigned [CVE-2017-0007](http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-0007) (under [MS17-012](https://technet.microsoft.com/en-us/library/security/ms17-012.aspx)) and patched. This particular bug only impacts PowerShell and the Windows Scripting Host, and not compiled code. **This bug is my first CVE and my first time reversing a patch. This post is a write-up of not only the bug, but the patch reverse-engineering process that I took as well. Since this is my first time doing this, there are bound to be errors. If I stated something incorrectly, please let me know so I can learn ** When executing a signed script, wintrust.dll handles validating the signature of that file. This was determined after looking at the exports. Ideally, if you take a Microsoft signed script and modify it, the integrity of the file has been compromised, and the signature should no longer be valid. Such validation is critical and fundamental to Device Guard, where its sole purpose is to prevent unsigned or untrusted code from running. CVE-2017-0007 circumvents this protection, allowing you to run any unsigned code you want by simply modifying a script that was previously signed by an approved signer. In this case, a Microsoft signed script was chosen since code signed by Microsoft needs to be able to run on Device Guard. For example, if we try to run an unsigned PowerShell script that executes restricted actions (e.g. instantiation of most COM objects), it will fail due to PowerShell being in [Constrained Language mode](https://blogs.technet.microsoft.com/kfalde/2017/01/20/pslockdownpolicy-and-powershell-constrained-language-mode/). Any signed and trusted PowerShell code that is approved via the deployed Code Integrity Policy is permitted to run in "FullLanguage" mode, allowing it to execute with no restrictions. In this case, our code is not signed nor trusted, so it is placed in Constrained Language mode and fails to execute correctly. ![](https://images.seebug.org/content/images/2017/04/unsigned_calc_com.png) Fortunately, Microsoft has scripts that are signed with their code signing certificate. You can validate that a script is indeed signed by Microsoft using sigcheck or the PowerShell cmdlet "[Get-AuthenticodeSignature](https://msdn.microsoft.com/en-us/powershell/reference/5.1/microsoft.powershell.security/get-authenticodesignature)". In this case, I grabbed a signed PowerShell script from the Windows SDK and renamed it to "MicrosoftSigned.ps1": ![](https://images.seebug.org/content/images/2017/04/valid_signed_script.png) When scripts like these are signed, they often contain an embedded authenticode signature within the body of the script. If you were to modify any contents of that file, the integrity of said file would be broken and the signature would no longer be valid. You can also simply copy the authenticode cert from a signed file and paste it into the body of an unsigned script: ![](https://images.seebug.org/content/images/2017/04/broken_signature.png) As you can see, the original contents of the script were replaced with our own code, and sigcheck reports that "The digital signature of the object did not verify", meaning the integrity of the file has been compromised and the code will be blocked from running, right? ![](https://images.seebug.org/content/images/2017/04/unsigned_execution.png) As you can see, our code executed anyway, despite the invalidated digital signature. Microsoft assigned this bug [CVE-2017-0007](http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-0007), classified under [MS17-012](https://technet.microsoft.com/en-us/library/security/ms17-012.aspx). The underlying issue here is that the error code returned by the function that ensures the file’s integrity never gets validated, resulting in successful execution of the unsigned code. So, what is the reason for the bug, and how was it fixed? Device Guard relies on wintrust.dll to handle some of the signature and integrity checks on signed files. Due to the nature of the bug, this was the first place I looked. [Bindiffing](https://www.zynamics.com/bindiff.html) wintrust.dll pre-patch (10.0.14393.0) and post-patch (10.0.14393.953) reveals a new chunk of code was added. While there was one other change to wintrust.dll, this was the only change that pertained to validating signed scripts. Due to this, is very likely to be the patch for the bug: ![](https://images.seebug.org/content/images/2017/04/bindiff.png) Looking closer, you will see that some code from "sub_18002D0F8" was removed: ![](https://images.seebug.org/content/images/2017/04/removed.png) Looking at the newly added block named "sub_18002D104", you will see that it contains some code from "sub_18002D0F8" as well as some additions. These particular functions don't have symbols, so we must refer to them as the defined names. Alternatively, you can also rename these functions in IDA to something more meaningful. ![](https://images.seebug.org/content/images/2017/04/deep_view_of_added_code.png) The text above is a bit small, but I will go into depth on what exactly was done. I won't go into specifics on using bindiff, but if you want to learn more I recommend you check out the [manual](https://www.zynamics.com/bindiff/manual/). Armed with the general location of the bug fix, I set out to identify exactly what was happening when our unsigned code was executed. Knowing that some code was removed from "sub_18002D0F8" and added to a new block named "sub_18002D104" made these two places a good starting point. First, I opened up the pre-patch version of wintrust.dll (10.0.14393.0) in IDA, and navigated to the sub that was modified in the patch (sub_18002D0F8). This function starts off by setting a few variables and then calls "SoftpubAuthenticode" ![](https://images.seebug.org/content/images/2017/04/original_softpubcall.png) Looking at "SoftpubAuthenticode" reveals that it calls another function named "CheckValidSignature": ![](https://images.seebug.org/content/images/2017/04/error_code_struc_applied.png) It makes sense that "CheckValidSignature" would handle validating the signature/integrity of the file being executed. Looking at this function, we can get the location of the last instruction before it returns. ![](https://images.seebug.org/content/images/2017/04/end_of_checkvalidsig.png) We can see the error code from "CheckValidSignature" in the eax register by setting a windbg breakpoint at the last instruction in the function, which is highlighted in yellow above. ![](https://images.seebug.org/content/images/2017/04/return_code_in_eax.png) In this case, the error code is "0x80096010", which translates to "[TRUST_E_BAD_DIGEST](https://msdn.microsoft.com/en-us/library/windows/desktop/aa376512(v=vs.85).aspx)", according to wintrust.h in the Windows SDK. This is why we see "The digital signature of the object did not verify." when running sigcheck on a modified signed file. After "CheckValidSignature" returns (via retn), we arrive back at "SoftpubAuthenticode". ![](https://images.seebug.org/content/images/2017/04/error_code_struc_applied1.png) "SoftPubAuthenticode" then goes on to call "SoftpubCallUI" and then returns back to "sub\_18002D0F8", all while keeping our error code "0x80096010" in the eax register. Now that we know what the error code is and where it is stored, we can take a close look at why our script was actually allowed to run, despite "CheckValidSignature" returning "TRUST\_E\_BAD\_DIGEST". At this point, we are resuming execution in sub\_18002D0F8, immediately after the call to "SoftpubAuthenticode". ![](https://images.seebug.org/content/images/2017/04/correct_bug.png) Since our error code is stored in eax, it gets overwritten immediately after returning from SoftpubAuthenticode via "move rax, [r12]". Since the error code stating that our script's digital signature isn't valid doesn't exist anymore, it never gets validated and the script is allowed to execute: ![](https://images.seebug.org/content/images/2017/04/continued_execution.png) With an understanding of exactly what the bug is, we can go look at how Microsoft patched it. In order to do so, we need to install KB4013429\. Looking at the new version of wintrust.dll (10.0.14393.953), we can explore "sub\_18002D104", which is the added block of code that was identified towards the beginning of the blog post. We know that the bug stemmed from the register holding our error code was being overwritten and not validated. We can see that the patch added a new call to "sub\_18002D4BC" following the return from "SoftPubAuthenticode". ![](https://images.seebug.org/content/images/2017/04/added_check.png) You may also notice in the picture above that our error code gets placed in the ecx register, and the instructions to overwrite the rcx register is now dependent on a test instruction, followed by a "jump if zero" instruction. This means that our error code, now stored in "ecx" will only get overwritten if the jump isn't followed. Looking at the newly introduced sub "sub\_18002D4BC", you will see this: ![](https://images.seebug.org/content/images/2017/04/new_function_check.png) This function returns a BOOL (0 or 1), depending on the result of operations performed on our error code. This addition checks to see if the call to “SoftpubAuthenticode” succeeded (< 0x7FFFFFFF) or if the return code matches “0x800B0109”, which translates to “CERT\_E\_UNTRUSTEDROOT”. In this case, SoftpubAuthenticode returned 0x80096010 (TRUST\_E\_BAD\_DIGEST) which does not match either of the described conditions, resulting in the function returning 1 (TRUE). ![](https://images.seebug.org/content/images/2017/04/al_getting_set.png) After setting "al" to "1" and returning back to the previous function, we can see how this bug was actually patched: ![](https://images.seebug.org/content/images/2017/04/after_al_set_continue.png) With "al" set to "1", the function does another logical compare to see if "al" is zero or not. Since it isn't, it sets the "r14b" register to "0" (since the ZF flag isn't set from the previous "test" instruction). It then does a last logical compare to check if "r14b" is zero. Since it is, it follows the jump and skips over the portion of code that overwrites the "rcx" register (leaving ecx populated with our error code). The error code eventually gets validated and the script is placed in Constrained Language mode, causing failed execution. ![](https://images.seebug.org/content/images/2017/04/blocked_execution.png) Cheers, Matt
idSSV:92871
last seen2017-11-19
modified2017-04-04
published2017-04-04
reporterRoot
titleMicrosoft Windows PowerShell Security Feature Bypass Vulnerability (CVE-2017-0007)