Detailed analysis of Windows vulnerability in MS14-066/CVE-2014-6321 Winshock
About MS14-066/CVE-2014-6321, that is, winshock vulnerability has been popular for a long time. Due to its wide impact, no poc announcement has been made so far. Beyondtrust was the first to trigger the vulnerability, and then security experts crashed. Recently, security researcher Mike Czumak released a more detailed report, but the poc is still not provided. Next, let's take a look at what the vulnerability is.
Go to the correct Branch
Here is the key code logic for triggering the vulnerability, which is located at the start of DecodeSigAndReverse of schannel. dll:
After entering the DecodeSigAndReverse function, call the CryptDecodeObject function and determine that the returned value goes into different branches. memcpy in the yellow code block in the lower left is the key to the vulnerability, therefore, you must let the program process judge that cmp ebx and 2fh are correctly redirected. That is, determine whether it is ECC.
This vulnerability affects IIS servers with SSL and Remote Desktop.
This debugging uses the win7 + IIS environment to enable the https service on port 443.
First, use OpenSSL to create a self-signed certificate and import it to applications in IIS. (The process is omitted here, everyone will)
The attacker needs to configure the internal permission to access the lsass.exe process context, and then click the breakpoint. Because windows SSL authentication is performed by this process.
Download the openssl source code of version 1.0.1j and modify it to trigger the vulnerability.
There are two changes:
437 of S3_clnt.c.
Re-compile openssl to access the configured IIS host and trigger the function DecodeSigAndReverse of the vulnerability:
Push the program process to DecodeSigAndReverse. I believe most security researchers can do this.
Next, let's continue to see what conditions can be met to go To the memcpy branch.
Detail Analysis
Please note that DecodeSigAndReverse called CryptDecodeObject twice at the beginning. According to the MSDN explanation, we can see from the code logic, this first CryptDecodeObject call sets pvStructInfo to null, calculates the buffer size required for decoding, and then passes it to SPExternalAlloc to request memory.
Before the second CryptDecodeObject call, pvStructInfo is 0, and cbEncoded points to the encrypted content.
Then, two calls to memcpy. The first memcpy only copies the directly decrypted length, which is a value;
The second memcpy call actually copies the content.
Then, the heapoverflow must occur in the second memcpy.
Let's take a look at whether we can control the length of the second memcpy, or reduce the size of the previously allocated memory.
Heapoverflow
After parameter tracing, the two data can be imported by the previous function.
The length of the second memcpy is directly read from this structure,
The memory size of the destination address is calculated based on the total length of the header description of the entire signature structure.
The total size of the header is first divided by 8 and then multiplied by 2. The calculated length is used to apply for the target address size of the second memcpy.
Of course, this structure is only the intermediate data when the signature is decrypted, not the original signature file data.
If it corresponds to the way the network packet is sent, It is roughly as follows:
Sig [1] = cbEncoded: Header, total size;
Sig [2] = \ x30 indicates that the data type cannot be changed. Otherwise, the program branch is changed.
Sig [3] = (sig [1]-1) memcpy length field. The larger the value, the better. If it exceeds \ x7f, an error is returned.
Sig [4] = \ x02
Sig [5] = 1
Sig [6] = 0 random data, set to 0 here
Sig [7] = \ x02 Similarly, representing the Data Type
Sig [8] = sig [1]-7 = \ x7a
Sig [9]… Sig [x]. This is the data filled with heapoverflow.
Sending data in this way will trigger the vulnerability, crash
In the heap, the overflow overwrite memory is as follows:
So far, the poc can achieve stable heap overflow. However, the Code covered by overflow is uncertain and there is no means to stably deploy the memory. It seems that it is difficult to manipulate the overflow data only through network packets, and the remote code execution effect cannot be achieved.
The time when a crash occurs after overflow is not necessarily determined by the time when the data is used.
Conclusion
The computing logic used by Windows to decrypt the signature is very complicated. Of course, the signature and the structure of the data packet itself are also very complicated. When the code believes in the description of the length in user data and does not check it, a malicious communication package can naturally cause heap overflow of windows code. At the same time, this code runs on the kernel permission, resulting in the confusing and influential winshock vulnerability.