In this
report I will analyze the procedure of a vulnerability of SMB protocol implemented
in Microsoft. As it is not a secret one, you may find more details on the
Internet.
Make a comment
if you have any idea. SHARE IS ENCOURAGED.
Overview
By
sending a malformed “Negotiate Protocol Response” packet, it may cause the SMB
Client to trigger an overflow in kernel pool. A successful exploitation can
result in a remote code execution. Besides, the attacker must convince the
client to send a “Negotiate Protocol Request” to server.
Technical Details
0x01 Critical Parameter
According
to some previous knowledge, we know that when a SMB server gets a “Negotiate
Protocol Request” packet, it will send back a response to the client with some
parameters as
“Word
Count”, ”Dialect Index”, …… ,”Max Buffer Size”, etc.
The Parameter
“Max Buffer Size” is defined in MSDN here
(http://msdn.microsoft.com/en-us/library/cc246326.aspx).
It represents that the buffer size to send and receive SMB messages in the
server. The max buffer size of clients to send SMB messages to the server depends
on this value. The size is from the beginning of the SMB header to the end of
the packet.
0x02 Procedure
In this
part, I will show you how the parameter triggers the vulnerability.
Let’s
take a look at the stack trace when the client crashes:
Figure
1. Stack Trace
As it
shows, we infer the pool is corrupt according to rdbss!_RxFreePool when it
caused a bug check.
So, the
entire process is :
The
client firstly read the “MaxBufferSize” from the response packet sent by the
server. Then it added 0x80 to that value as a final size to allocate a paged pool
in memory.
Figure
2. Memory Allocation
Figure
3. Runtime Parameters
When the
allocation succeeded, it returned the beginning of the pool address to EAX as
below shows:
Figure
4. Returned Address
Let’s
take a look at the pool allocated.
Figure
5.Pool information
When the
allocation was done, following instructions initialized the memory with zero by
obtaining the MaxBufferSize from ESI+138h.
Figure
6.Initialize the memory
When the
program ran to 0xb2c73258, instruction here caused the overflow.
Figure
7. Overflow
We use
!pool to see some information about this chunk
Figure
8. Pool Information
It is
obvious that command at 0xb2c7325c overwrited the size of the next pool which caused
a bug check when the program called mrxsmb!_RxFreePool to free the corrupt pool.
Figure
9 . Bug Check
0x03 Version information

Figure
10. Version