This is the final post in the three-part series covering MS08-001. In this post we’ll look at the IGMP vulnerability (CVE-2007-0069) and why we think successful exploitation for remote code execution is not likely.
This vulnerability is around Windows’ handling of the IGMP and MLD protocols. These two protocols are used to control multicast traffic over IPv4 and IPv6 networks, enabling hosts to advertise their intention to send & receive multicast traffic. This allows routers to maintain the necessary state so that they can forward data to the network segments. IGMP is the protocol used for IPv4, and MLD is used for IPv6 multicast.
Source-specific multicast (SSM) is a recent addition to IP multicast and allows a host to receive multicast traffic from only specific sources. IGMPv3 and MLDv2 are the versions of the protocols that support SSM.
A vulnerability in the tcpip.sys driver in Windows exists due to the way the TCP/IP stack handles network packets specifying SSM data. This bug can be exploited to gain remote code execution (RCE) in the context of the kernel (SYSTEM). This attack can be performed by remote, anonymous attackers.
The first question you are probably asking is "How likely is exploitation of this issue?"
Even though this bulletin is rated Critical for XP and Vista (the bulletin describes mitigating factors that lower the severity on Windows Server 2003) there are a number of factors that make exploitation of this issue difficult and unlikely in real-world conditions:
- An attack is likely to cause high CPU usage by the target, unless packets are sent slowly. Due to the way the TCP/IP code processes incoming SSM messages, the machine will consume large amounts of CPU when it is under attack. This can be controlled to some extent by the attacker by sending fewer packets per second. An attacker trying to send packets blindly at full speed will cause the target to use 100% CPU and become unresponsive. This has the effect of causing the TCP/IP code to drop messages, which makes it harder for the attacker to control the attack and make exploitation reliable.
- The attack is timing-sensitive, due to the nature of the IGMP protocol and the high CPU usage that is likely on the target machine.
The IGMP protocol requires the use of a timer which is used to trigger a multicast report (which triggers the vulnerable code). The timer is created when the initial IGMPv3 or MLDv2 query message is received. The TCP/IP stack chooses a random value between (0,MaxResponseTime), where MaxResponseTime is the value in the received query (attacker controlled). Each new IGMPv3/MLDv2 query that is received can have a different MaxResponseTime value in it. The existing timer is updated by selecting a random number between (0,MaxResponseTime), but only if the new value is smaller than the current value. This means that the attacker can:
- Specify the upper-limit of the timer value
- Trigger an immediate timer expiration at will. This is useful when launching an attack since the attack packets can use a large MaxResponseTime value, except for the last packet which uses a small value. This will then trigger the timer soon after the last packet is received.
However, since the timer value is chosen randomly, the attacker does not know when the timer will expire. Let’s assume the attack requires 300 packets worth of data. The attacker can send their packets, but the timer may expire mid-way through the transmission. When the timer fires, the list is emptied (and no overflow happens). The 2nd half of the attack continues and fills the list again, but there is no longer enough data to successfully attack the vulnerability.
The attacker can run their attack non-stop, and eventually they will be lucky enough to have the timer fire with the appropriate conditions to trigger the vulnerability. However, they don’t know for sure how many packets to send, or what will be in the buffer when they trigger the vulnerability.
To illustrate this in effect, this is a dump from a kernel debugger, showing the timer values as the attack is running:
unsigned long 0xd02 <- Initial timer value chosen randomly
unsigned long 0x4b6 <- Timer value reduced to a new random value
unsigned long 0x467
unsigned long 0x2ea
unsigned long 0x6b
unsigned long 0x28
unsigned long 0x16
Timed out! <- The timer expires and the buffer is emptied
unsigned long 0x1806 <- Attack continues, a new timer value is chosen randomly
unsigned long 0xa71 <- Timer value reduced to a new random value
unsigned long 0x291
unsigned long 0x15c
unsigned long 0xab
unsigned long 0x9b
unsigned long 0x27
Timed out! <- The timer expires and the buffer is emptied
- The state of the target machine is unpredictable since the target may have dropped some of the attacker's IGMP packets (e.g. if they are sent too fast), and the timing sensitivity may have flushed some data from the target's memory before the issue was triggered.
- The target machine will only store data in the attacker's packets that is unique (unique IP addresses), so the attacker cannot repeat the same value across large sections of the target machine's memory. Any exploit code would also need to be encoded to appear as unique IP addresses.
- The issue causes pool corruption which is similar to heap buffer overruns in user-mode code. These are typically harder to exploit reliably. Unsuccessful exploitation attempts will result in a bugcheck (a.k.a. "blue screen" or BSOD).
This concludes the end of our three-part series as it relates to MS08-001.
At the end, we probably should note that you might be wondering if we are releasing too much technical detail about this vulnerability, which somehow could help miscreants develop an attack. Please be assured that these details cannot be used to create an attack and that the security of customers is our primary concern.
Update: Updated with correct CVE number.
- Security Vulnerability Research & Defense