The results are based on Windows XP SP3 x86. The vulnerability itself is contained in the functions FindFirstFileExW and FindNextFileExW of the library kernel32.dll, which copy data received from the native function NtQueryDirectoryFile with the help of memmove. The problem is that a number received from NtQueryDirectoryFile is used as the size of a source buffer for the copy function, however, it may happen that the size of a destination buffer can be smaller than the result of NtQueryDirectoryFile.
This vulnerability affects all applications, which use the functions of the families FindFirstFile/FindNextFile. The first application that comes to my mind is explorer.exe. An attacker only needs to make a user open a link to the malware resource. And, if everything is going well, they will be able to execute code with the same user rights as the current user. The remote execution script according to Microsoft FAQ is possible only via UNC share or WebDAV. A UNC (Universal Naming Convention) path can indicate a file share network resource running on the basis of the SMB protocol. Linux with the Samba service, which allows creating shared fields basing on the protocol, was chosen for the test. We wanted to carry out an attack in accordance with the following scheme.
Linux has a similar restriction (not a path length, but a file name length), which is 255 characters. It is only needed to modify the resources of the Samba server to send a vulnerable Windows machine a directory listing with file names, which length exceeds 255 characters. The function smbd_marshall_dir_entry from trans2.c (Samba 3.6.6), which partially forms the server task, is one of the holes for malware injection. For the first test, the name of the output files was extended over 0x100 bytes and filled with the constant 0xfeeddead. Trying to use a modified server from a vulnerable machine, you can see the following.
The screenshot shows that explorer.exe tried to read DWORD by the address from the EDX register. The read value participates in creating an address for the call. It's easy to see ascending the call stack that the first two parameters of the function RecentDocs_Enum are under control, besides they are rendered further. These values can be rewritten because they are located in a stack (see the scheme below).
The function CFSFolder_CreateEnum allocates memory of size 0x498 for an instance of the class CFileSysEnum; this chunk contains the structure WIN32_FIND_DATA with offset 0x224. A pointer to this structure is transferred to the vulnerable function FindFirstFileEx, which rewrites the values that allow control hijacking.
It is necessary to conduct a heap-spray attack to exploit this vulnerability. File names received by CShellBrowser2 are the objects for heap spraying in this case. Therefore, it is needed to create a lot of files on a shared network resource to conduct a heap-spray attack. The figure below provides the attack scheme. Note: the DEP (Data Execution Prevention) system is not considered in this scheme; it is evident that shellcode is in the heap, which should not be executable.
One of the attack problems is server response fragmentation into several SMB packets. The driver mrxsmb.sys responsible for the SMB protocol includes the function MrxSmbUnalignedDirEntryCopyTail. This function checks the length of received names transferred to the user mode. If the limit of 0x200 bytes is exceeded, the function will display the error STATUS_INVALID_NETWORK_RESPONSE (0xC00000C3), and then NtQueryDirectoryFile will stop sending names for FindNextFile.
This check can be bypassed as follows. First of all, it is necessary to create a set of files, which will conduct the heap-spray attack, and then to remove all the files from the directory and create a file, the name of which is the vulnerability trigger. The Samba server, in case of changes in the file system with a connected server, will send a packet with the function NT_NOTIFY, which will make the client repeat the request FIN_FIRST2 to the server having received only one malware name. Besides, the file names received earlier will remain in memory. Moreover, it is possible to control the order of the names, because they are sorted by name. It is worth noting that the names received from the Samba server should be unique; it is provided by allocating 5 bytes from the main file name field to the unique identifier.
It is also worth noting that the file name transport supports interaction via the SMB protocol in double-byte Unicode.
It restricts addresses rewritten on the vulnerable client, but due to the fact that the Samba server output is modified after conversion of single-byte to double-byte characters, these restrictions are insignificant, though they complicate the modified server's running process. Sending a big data packet, the server divides it into parts, and the client having received another such data part sends the sever a name, starting with which it should proceed the transaction (see the figure below).
Due to the fact that when conducting the heap-spray attack unreal data is output, then the name to continue the output will be unreal as well. That is why it is needed to render the received continue_name in a real name on the server, with which it is necessary to continue.
This construction allows code execution on a vulnerable machine with probability 1/7. Finally, we should say that the vulnerability can be easily exploited "in a wild life", though for creation of a combat exploit, one will have to solve the problem with DEP and find optimizing algorithms for heap spraying (to increase the probability of success).
Author: Kirill Nesterov, Positive Research.