📜 ⬆️ ⬇️

How to study the critical DHCP vulnerability in Windows 10 has led to the detection of two more security errors



Image: Unsplash

As described in the previous article about CVE-2019-0726 , sometimes searching for details about a known vulnerability leads to the discovery of a new vulnerability. And in some cases, these new vulnerabilities are more than one.
')
The article dealt with two functions of the dhcpcore.dll library: the briefly mentioned UpdateDomainSearchOption and the DecodeDomainSearchListData that it calls in more detail. As always happens when searching for vulnerabilities, even if important conclusions at the end are reduced to one or two functions, in the process of analysis you have to look through a much larger amount of code. And sometimes the eye clings to trifles that are not related to the current task, but may have independent significance or come in handy later. Suppose that at the moment there is no time to pay attention to them, but such trifles are deposited on the subcortex and, if after a certain period of time it becomes possible to return to them and check their guesses, re-emerge in consciousness.

That is what happened this time. When studying the DhcpExtractFullOptions function, which is responsible for processing all the options specified in the DHCP response from the server, in particular, the calling UpdateDomainSearchOption, two arrays on the stack of 256 elements each immediately attract attention:



At the same time, there is no noticeable presence of any checks that limit the values ​​of the iterators of these arrays. Since at that moment we were reviewing another vulnerability, this information was irrelevant. Therefore, it remained only to remember this place in the code in order to return to it later.

Analysis


A couple of weeks pass, and we again recall the previously received function DhcpExtractFullOptions. We appeal to it in the disassembler, we brush the previously not completely disassembled pieces of code and try to understand what two static arrays intrigued us are used for.

At the very beginning of the execution of the function, the arrays and their iterators are reset:



The function is engaged in the analysis of all options in the package received from the DHCP server, the collection of information from them and its subsequent processing. In addition, according to the results of the analysis, she also writes the corresponding event in the ETW service (Event Tracing for Windows). It is in the event logging that the buffers of interest take part. Together with a large amount of other data, they are passed to the EtwEventWriteTransfer procedure. The work on preparing all the data for logging is quite voluminous and does not matter much for the vulnerability we are considering, so we can do without illustrations.

It is more important to determine how these buffers are filled. Filling in the parse option cycle. First, a function with a talking name ParseDhcpv4Option is called for the current option received for processing, which either fills the fields of the dhcp_pointers object based on the incoming data or marks an unfamiliar option when it encounters an option ID with a value for which there is no handler.



Upon returning from ParseDhcpv4Option, the value of the identifier of the current option_tag is written to the next element of the array all_tags, the first array of interest to us. If the function encountered an unfamiliar option and, accordingly, did not set the is_known_option flag, then the identifier value is also written to the next element of the second array, unknown_tags. Naturally, the meaningful names of the variables in this article have already been obtained from the results of the code analysis.

Thus, the array all_tags stores the tags of all options from the incoming message, and the array unknown_tags stores tags for only those options unknown to the parser. At the same time, there is no verification of the index values ​​of these arrays at all. Consequently, the values ​​of such indices can exceed 256 and lead to writing beyond the memory allocated on the stack for arrays. To overflow the first array, it is sufficient to send a packet from the DHCP server with more than 256 options. The same is true for the second array, the only difference being that the options that the client cannot process are sent.

Exploitation


Let us try now on a practical example to make sure that our conclusions are correct. To begin with, pay attention to the fact that the option tags occupy one byte, while the elements of the arrays are of type int, that is, they are four-byte. Thus, we have an overflow in which we control every fourth byte, and the rest when overwritten are reset.



To test our assumption, the easiest way is to overwrite the security cookie stored on the stack of the function in question, which will cause an exception related to the security check. Let us simulate a situation in which the DHCP server sends a sufficient number of options for rewriting. Let it be 0x1a0 (416) options with id 0xaa and zero size. Thus, each option takes up two bytes, and the full packet size with all the headers will be 1100–1200 bytes. This value is within the MTU for Ethernet, therefore, there is reason to believe that the message will not be fragmented, which will allow us to avoid possible adverse effects.

We send the package generated in the described manner in response to a request from a DHCP client and intercept an exception on the client machine in the corresponding svchost.exe process:



As can be seen from the stack trace, the stack cookie and the return address of the function were rewritten with the option identifiers from our package.

Of course, creating a working exploit for this error will require quite a lot of effort from the attacker. On modern systems, the buffer overflow on the stack is quite complex and time-consuming in the operation of vulnerability due to all the existing protective mechanisms. On the other hand, we should not forget that all these mechanisms either protect against rewriting of the return address and exception handlers, either prohibit the execution of code in regions of memory not intended for this, or interfere with the prediction of addresses. For example, they cannot help in any way against overwriting the stack stored between the overflowing buffer and the return address of local variables. And the DhcpExtractFullOptions function in question contains several potentially dangerous variables in this range.

Again, we write to Microsoft about the error found. After a brief correspondence and analysis of the application that took about a week, we get an answer that a CVE-identifier is being prepared for the described vulnerability, a correction is scheduled for release in March, and information about the vulnerability is already available to Microsoft, was reported by someone earlier. The fact is, generally speaking, not surprising, because the error lies literally on the surface, and buffers that do not contain boundary checks of indices always attract attention first and can often be detected by automatic analysis tools.

In March, as was stated, an update is issued, correcting the described error, which received the identifier CVE-2019-0697 . The researcher who reported the information earlier turned out to be Mitch Adair, the Microsoft employee who discovered the DHCP vulnerability CVE-2019-0547 , which was fixed in January.

Author : Mikhail Tsvetkov, Specialist, Application Technologies Analysis Department, Positive Technologies.

Source: https://habr.com/ru/post/448600/


All Articles