Surprise from kernel32 for network resources (MS12-081, a detailed analysis of the vulnerability in the Microsoft File Handling Component)
On the eleventh of December last year, Microsoft released a bulletin related to a vulnerability discovered in the Microsoft File Handling Component. The vulnerability has been assigned the rank of critical and the category Remote code execution. Remote code execution occurs when the victim opens a shared network share with content that was formed by the attacker in a special way. Details of operation are given in this report.
The results were obtained on Windows XP SP3 x86. The vulnerability itself is located in the FindFirstFileExW and FindNextFileExW functions of the kernel32.dll library, which copy data obtained from the native NtQueryDirectoryFile function using a memmove. The problem is that the number received from NtQueryDirectoryFile is transferred as the source buffer for the copy function, although it is possible that the size of the receive buffer may be smaller than the result of issuing NtQueryDirectoryFile.
The impact of this vulnerability applies to all applications using FindFirstFile / FindNextFile family functions. The first such application that occurred to me was explorer.exe. For the exploitation, an attacker will only need to force the user to open a link to the malicious resource, and if successful, he will be able to execute the code with the rights of the user who opened the link. The remote operation scenario, as suggested by the FAQ section of the Microsoft newsletter, is possible through the UNC share or via the WebDAV path. The UNC (Universal Naming Convention) path may indicate a network file sharing resource that operates on the basis of the SMB protocol. For the test, Linux was chosen with the Samba service, which allows you to create “shared” folders based on this protocol. As a result, I wanted to simulate the following scheme of a remote attack. ')
On the Linux platform, there is a similar limit (not only on the length of the path, but on the length of the file name), equal to 255 characters. In order to transfer to the vulnerable Windows machine a directory listing with file names that are longer than 255 characters, you can simply correct the Samba server source code. One of the places where the malicious name is introduced can be the smbd_marshall_dir_entry function from trans2.c (Samba 3.6.6), which partially forms a server issue. For the first test, the name of the output files was expanded to 0x100 bytes and filled with the constant 0xfeeddead. When you try to access a modified server from a vulnerable machine, you can observe the following picture.
As you can see in the screenshot, explorer.exe tried to read the dword at an address from the EDX control register. The read value is involved in the formation of the address at which the call occurs. If you go up the call-stack to a higher level, you will notice that the first two parameters of the function RecentDocs_Enum are controlled, besides, both of them are passed on. Rewriting of these values ​​is possible because of their location on the heap (the diagram is presented below).
In the CFSFolder_CreateEnum function, memory size 0x498 is allocated for an instance of the CFileSysEnum class; in this chunk with offset 0x224 is located the structure WIN32_FIND_DATA. A pointer to this structure is passed to the vulnerable function FindFirstFileEx, which overwrites values ​​that allow control to be intercepted.
To exploit this vulnerability, heap spray needs to be performed. The objects to fill the heap in this case will be the file names obtained by the CShellBrowser2 component. Therefore, to conduct heap spray, you need to create a large number of files on a network share. The attack pattern is shown in the figure below. Note: this scheme does not include the Data Execution Prevention (DEP) system; the shellcode, as you can see, is in a heap that should be non-executable.
One of the problems of the attack is the fragmentation of the server's response to several SMB packets. In the mrxsmb.sys driver, which is responsible for the operation of the SMB protocol, there is a function MrxSmbUnalignedDirEntryCopyTail. This function checks the length of the received names that are passed to the user mode, and when the limit is exceeded, 0x200 bytes will display the error STATUS_INVALID_NETWORK_RESPONSE (0xC00000C3), and having received an error, NtQueryDirectoryFile will stop issuing names for FindNextFile.
This check can be circumvented as follows. First, create a set of files that will perform heap spray, and then delete all files from the directory and create one file whose name will trigger the vulnerability. In the event of a change in the file system when the client is connected, the Samba server will send a packet with the NT_NOTIFY function, which will force the client to repeat the FIN_FIRST2 request to the server, having received only one malicious name. In this case, the names of the files received earlier will remain in memory. In addition, you can control the order of the names as they are sorted by name. It is also worth noting that the names obtained from the Samba server must be unique; This can be achieved by allocating 5 bytes to the unique identifier from the main field of the file name.
It is worth noting that the transport of file names interacts via the SMB protocol in two-byte unicode.
This imposes certain restrictions on the addresses that are overwritten on the vulnerable client, but since the modification of the output of the Samba server occurs after converting from one-byte to two-byte characters, these restrictions are not significant - although they introduce some complexity in the process of the modified server. Sending a large data packet, the server breaks it apart, and the client, after receiving the next such part of the data, gives the server a name, starting with which he needs to continue issuing (see the figure below).
Since during the implementation of heap spray, unrealistic data is output, then the name from which the issue should be continued will also be unrealistic, and therefore it is necessary to map the resulting continue_name to the real name on the server from which to continue.
As a result, the resulting design allows you to execute code on a vulnerable machine with a probability of approximately 1/7. In conclusion, it can be said that vulnerability may well be exploited “in the wild”, although to create a combat exploit, you will have to solve a problem with DEP, as well as optimize the heap spray (to increase the likelihood of successful execution).