Surprise from kernel32 for network resources (MS12-081, detailed analysis of vulnerabilities in Microsoft File Handling Component)
On December 11 last year, Microsoft released a bulletin related to a vulnerability discovered in the Microsoft File Handling Component. The vulnerability was assigned the critical rank and the Remote code execution category. Remote code execution occurs when a victim opens a shared network resource with content generated by an attacker in a special way. Details of operation are provided 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 NtQueryDirectoryFile native function using memmove. The problem is that the number obtained from the NtQueryDirectoryFile is passed as the size of the source buffer for the copy function, although it is possible that the size of the destination buffer may be smaller than the result of issuing the NtQueryDirectoryFile.
The impact of this vulnerability extends to all applications that use the functions of the FindFirstFile / FindNextFile family. The first such application that came to my mind was explorer.exe. For exploitation, it will be enough for an attacker to force the user to open a link to a 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 Microsoft FAQ section, is possible through the UNC share or via the WebDAV path. The UNC (Universal Naming Convention) path can point to a file sharing network 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 remote attack scheme.

On the Linux platform, there is a similar restriction (not only on the path length, but on the length of the file name), equal to 255 characters. In order to transfer a directory listing with file names exceeding 255 characters in length to a vulnerable Windows machine, you can simply correct the Samba server sources. One of the places for introducing a malicious name may be the smbd_marshall_dir_entry function from trans2.c (Samba 3.6.6), which partially forms the server output. For the first test, the name of the output files was expanded by 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 the address from the EDX controlled register. The read value is involved in the formation of the address at which the call occurs. If you go up a level on the call stack, you will notice that the first two parameters of the RecentDocs_Enum function are controlled, in addition, both of them are passed on. Overwriting these values is possible due to their location on the heap (the diagram is presented below).

The CFSFolder_CreateEnum function allocates memory of size 0x498 for an instance of the CFileSysEnum class; in this chunk with offset 0x224 the structure WIN32_FIND_DATA is located. A pointer to this structure is passed to the vulnerable FindFirstFileEx function, which overwrites the values that allow for control interception.
To exploit this vulnerability, you need to carry out heap spray. The objects to fill the heap in this case will be the file names received by the CShellBrowser2 component. Therefore, to conduct heap spray, you need to create a large number of files on a network share. The attack scheme is shown in the figure below. Note: the Data Execution Prevention (DEP) system is not taken into account in this scheme; shellcode, as you can see, is in the heap, which must be unenforceable.

One of the problems of carrying out an attack is fragmentation of the server’s response to several SMB packets. The mrxsmb.sys driver, which is responsible for the operation of the SMB protocol, has the MrxSmbUnalignedDirEntryCopyTail function. This function checks the length of the received names, which are transferred to user mode, and if the limit is exceeded by 0x200 bytes, it will throw the STATUS_INVALID_NETWORK_RESPONSE (0xC00000C3) error, and when it receives the error, NtQueryDirectoryFile will stop issuing names for FindNextFile.
This check can be circumvented as follows. First you need to create a set of files that will implement heap spray, and then delete all the files from the directory and create one file, the name of which will be the trigger of the vulnerability. In case 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, receiving 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 from the main field of the file name to a unique identifier.
It is worth noting that the file name transport communicates via the SMB protocol in double-byte Unicode.

This imposes certain restrictions on the addresses that are rewritten on the vulnerable client, but since the modification of the Samba server issuance occurs after conversion from single-byte to double-byte characters, these restrictions are insignificant - although they introduce some complexity into the operation of the modified server. By sending a large packet of data, the server breaks it into parts, and the client, after receiving another such part of the data, gives the server a name, starting from which it needs to continue issuing (see. Fig. Below).

Since unrealistic data is provided during the heap spray, the name from which it is necessary to continue issuing will also be unrealistic, and therefore it is necessary to map the received continue_name to the real name on the server from which it is necessary to continue.
As a result, the resulting construction allows code to be executed on a vulnerable machine with a probability of approximately 1/7. In conclusion, it can be said that the vulnerability can well be exploited “in the wild”, although to create a combat exploit it is necessary to solve the problem with DEP, as well as optimize heap spray (to increase the likelihood of a successful execution).
Video demo:
Modified source .
Posted by Kirill Nesterov, Positive Research Center.
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 NtQueryDirectoryFile native function using memmove. The problem is that the number obtained from the NtQueryDirectoryFile is passed as the size of the source buffer for the copy function, although it is possible that the size of the destination buffer may be smaller than the result of issuing the NtQueryDirectoryFile.
The impact of this vulnerability extends to all applications that use the functions of the FindFirstFile / FindNextFile family. The first such application that came to my mind was explorer.exe. For exploitation, it will be enough for an attacker to force the user to open a link to a 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 Microsoft FAQ section, is possible through the UNC share or via the WebDAV path. The UNC (Universal Naming Convention) path can point to a file sharing network 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 remote attack scheme.

On the Linux platform, there is a similar restriction (not only on the path length, but on the length of the file name), equal to 255 characters. In order to transfer a directory listing with file names exceeding 255 characters in length to a vulnerable Windows machine, you can simply correct the Samba server sources. One of the places for introducing a malicious name may be the smbd_marshall_dir_entry function from trans2.c (Samba 3.6.6), which partially forms the server output. For the first test, the name of the output files was expanded by 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 the address from the EDX controlled register. The read value is involved in the formation of the address at which the call occurs. If you go up a level on the call stack, you will notice that the first two parameters of the RecentDocs_Enum function are controlled, in addition, both of them are passed on. Overwriting these values is possible due to their location on the heap (the diagram is presented below).

The CFSFolder_CreateEnum function allocates memory of size 0x498 for an instance of the CFileSysEnum class; in this chunk with offset 0x224 the structure WIN32_FIND_DATA is located. A pointer to this structure is passed to the vulnerable FindFirstFileEx function, which overwrites the values that allow for control interception.
To exploit this vulnerability, you need to carry out heap spray. The objects to fill the heap in this case will be the file names received by the CShellBrowser2 component. Therefore, to conduct heap spray, you need to create a large number of files on a network share. The attack scheme is shown in the figure below. Note: the Data Execution Prevention (DEP) system is not taken into account in this scheme; shellcode, as you can see, is in the heap, which must be unenforceable.

One of the problems of carrying out an attack is fragmentation of the server’s response to several SMB packets. The mrxsmb.sys driver, which is responsible for the operation of the SMB protocol, has the MrxSmbUnalignedDirEntryCopyTail function. This function checks the length of the received names, which are transferred to user mode, and if the limit is exceeded by 0x200 bytes, it will throw the STATUS_INVALID_NETWORK_RESPONSE (0xC00000C3) error, and when it receives the error, NtQueryDirectoryFile will stop issuing names for FindNextFile.
This check can be circumvented as follows. First you need to create a set of files that will implement heap spray, and then delete all the files from the directory and create one file, the name of which will be the trigger of the vulnerability. In case 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, receiving 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 from the main field of the file name to a unique identifier.
It is worth noting that the file name transport communicates via the SMB protocol in double-byte Unicode.

This imposes certain restrictions on the addresses that are rewritten on the vulnerable client, but since the modification of the Samba server issuance occurs after conversion from single-byte to double-byte characters, these restrictions are insignificant - although they introduce some complexity into the operation of the modified server. By sending a large packet of data, the server breaks it into parts, and the client, after receiving another such part of the data, gives the server a name, starting from which it needs to continue issuing (see. Fig. Below).

Since unrealistic data is provided during the heap spray, the name from which it is necessary to continue issuing will also be unrealistic, and therefore it is necessary to map the received continue_name to the real name on the server from which it is necessary to continue.
As a result, the resulting construction allows code to be executed on a vulnerable machine with a probability of approximately 1/7. In conclusion, it can be said that the vulnerability can well be exploited “in the wild”, although to create a combat exploit it is necessary to solve the problem with DEP, as well as optimize heap spray (to increase the likelihood of a successful execution).
Video demo:
Modified source .
Posted by Kirill Nesterov, Positive Research Center.