In November 2016, as part of my FortiGuard research work, I discovered and reported on an iSNS server memory corruption vulnerability in Microsoft Windows Server. On patch Tuesday of March 2017, Microsoft released the Security Bulletin MS17-012 that contain the fix for this vulnerability and identifies it as CVE-2017-0104.
This vulnerability could lead to remote code execution, and is rated as critical by Microsoft. The vulnerability affects Windows Server 2008, 2012, and 2016 versions. Microsoft recommends installing this update immediately.
In this blog I will share the details of this vulnerability.
To reproduce the vulnerability, you can follow the steps below.
1. On Windows Server 2016, install "iSNS Server service" in "Server Manager" by following the "Server Manager" install wizard and checking the option "iSNS Server Service." See the screenshot in Figure 1.
Figure 1. Install iSNS Server service
2. On another machine, such as Windows 7, run the PoC in Command Prompt, such as "poc_isns_final.py 10.0.0.135 3205". 10.0.0.135 is the IP address of Windows Server 2016, and 3205 is the port number where "iSNS Server service" is running. After the attack packet is sent to the target, you can see that the iSNS Server service of the Windows Server 2016 stops working, or automatically restarts with a new process id. The attack can be repeated until the iSNS Server service stops working. Figure 2 is the capture of the attack packets.
Figure 2. The capture of the attack packets
This vulnerability is caused because Windows Server doesn’t correctly parse the attribute “Portal TCP/UDP Port” in the malformed iSNS packet. So let’s take a look at it first. See Figure 3.
Figure 3. The data in the attack packet
The vulnerability is triggered when parsing the crafted attribute (00 00 00 11). It results in 0x0C (smaller than 0x20) being returned as size, then the 0x0C size is used in memory allocation and initialization. In the memory allocation/initialization function, 0x2C bytes memory is allocated and 0x0C bytes of them (from offset 0x20 to 0x2B) are initialized (set to zero.) But in subsequent code, the vulnerable function gets the memcpy size from the previously allocated object at its address+0x30. That is, it gets the memcpy size from uninitialized memory, which contains garbage data. When the PoC is run many times, multiple 0x2C bytes buffers are allocated. Once the value in the allocated object at its address+0x30 is not equal to 0, for example 0x20000000 (generally it’s larger than 0x20000000), the memcpy function tries to copy 0x20000008 bytes from the source buffer to the destination buffer. This causes a read access violation in the source buffer and results in memory corruption.
Following is the code snippet of the vulnerable function.
Following is the code snippet of the memory allocation and initialization function:
Following is the code snippet of the function iSNSCreatePGObject:
In summary, this vulnerability is caused by incorrectly parsing a crafted iSNS packet, which results in a small size (smaller than 0x20) being used to allocate memory buffer. Then, in subsequent code, the garbage data in uninitialized memory is read as the memcpy size, which causes memory corruption.
Successful exploitation of this vulnerability could lead to remote code execution.
All users of vulnerable versions of the Microsoft Windows Server are encouraged to upgrade to the latest version of this software. Additionally, organizations that have deployed Fortinet IPS solutions are already protected from this vulnerability with the signature MS.Windows.iSNS.Server.Memory.Corruption.
Sign up for weekly Fortinet FortiGuard Labs Threat Intelligence Briefs and stay on top of the newest emerging threats.