[NT] Vulnerability Report for Windows SMB DoS

From: support@securiteam.com
Date: 08/25/02


From: support@securiteam.com
To: list@securiteam.com
Date: Sun, 25 Aug 2002 21:00:11 +0200 (CEST)

The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com
- - promotion

When was the last time you checked your server's security?
How about a monthly report?
http://www.AutomatedScanning.com - Know that you're safe.
- - - - - - - - -

  Vulnerability Report for Windows SMB DoS
------------------------------------------------------------------------

SUMMARY

SMB stands for "Server Message Block" and is also known as CIFS (Common
Internet File System). This protocol is intended to provide an open
cross-platform mechanism for client systems to request file services from
server system over a network. Current CIFS implementation under Windows
runs over port TCP/139 and/or port TCP/445 (Direct Host), depending
whether NetBIOS over TCP/IP is enabled or not.

The SMB_COM_TRANSACTION command allows the client and the server to define
functions specific to a particular resource on a particular server. The
functions supported are not defined by the protocol itself but by client
and server implementations.

By sending a specially crafted packet requesting the NetServerEnum2,
NetServerEnum3 or NetShareEnum transaction, an attacker can mount a denial
of service attack on the target machine. It might be possible to abuse
this vulnerability to execute arbitrary code, although the research
performed so far cannot confirm this possibility (see 'Technical
Description' below for information that is more precise).

In order to exploit the vulnerability a user account is needed for the
NetShareEnum transaction and only anonymous access is necessary for
NetServerEnum2 and NetServerEnum3.

Windows operating system ship with anonymous access enabled by default and
is therefore vulnerable to a denial of service attack.

The effect of an attack will trigger an operating system halt (Blue
Screen) as shown below (memory addresses may vary):

 *** STOP: 0x0000001E (0xC0000005, 0x804B818B, 0x00000001, 0x00760065)
 KMODE_EXCEPTION_NOT_HANDLED
 *** Address 804B818B base at 80400000, DateStamp 384d9b17 0 ntoskrnl.exe

The physical memory is dumped and the system restarted (unless configured
otherwise).

DETAILS

Vulnerable systems:
The problem was identified and tested on:

 - Windows NT 4.0 Workstation/Server
 - Windows 2000 Professional/Advanced Server
 - Windows XP Professional

With all service packs and security HotFixes applied.

Solution/Vendor Information/Workaround:
Microsoft has released a fix to the problem. Refer to Microsoft Security
Bulletin MS02-045 for patches and fixes to vulnerable systems.

 
<http://www.microsoft.com/technet/treeview/?url=/technet/security/bulletin/MS02-045.asp> http://www.microsoft.com/technet/treeview/?url=/technet/security/bulletin/MS02-045.asp

Workarounds:
 - Disable anonymous access (NULL connections). This will not prevent
legitimate users from abusing the vulnerability.

 - Block access to the SMB ports from untrusted networks. Blocking access
to ports tcp/445 and tcp/139 at the network perimeter will prevent attacks
from untrusted parties. However, this is not a viable solution for
environment was file and printing services are needed for legitimate
users.

 - Shutdown the Lanman server (net stop lanmanserver). This prevents
exploitation from any attacker but removes all file and print sharing
functionality from the vulnerable server. It might not be a viable
solution in many environments.

Technical Description - Exploit/Concept Code:
The following analysis was performed on a Windows 2000 Advanced Server
(Service Pack 2).

The attack consists of sending (after establishing a SMB session) a
specially crafted SMB_COM_TRANSACTION packet requesting the
NetServerEnum2, NetServerEnum3 or NetShareEnum functions of the Microsoft
Windows Lanman Remote API Protocol.

The format of this packet consists of a SMB Header plus the Transaction
request. The transaction request has the following format:

 Transaction Request Format
 ===============================================
 +0 Word Count (BYTE)
 +1 Total Parameter Count (WORD)
 +3 Total Data Count (WORD)
 +5 Max Param Count (WORD)
 +7 Max Data Count (WORD)
 +9 Max Setup Count (BYTE)
 +10 (0Ah) Reserved (BYTE)
 +11 (0Bh) Flags (WORD)
 +13 (0Dh) Timeout (DWORD)
 +17 (11h) Reserved (WORD)
 +19 (13h) Parameter Count (WORD)
 +21 (15h) Parameter Offset (WORD)
 +23 (17h) Data Count (WORD)
 +25 (19h) Data Offset (WORD)
 +27 (1Bh) Setup Count (BYTE)
 +28 (1Ch) Reserved (BYTE)
 +29 (1Dh) Byte Count (WORD)
 +31 (1Fh) Transaction Name '\PIPE\LANMAN\x00' (13 BYTES)
 +44 (2Ch) Parameters

 Parameters
 ===============================================
 +0 Function Code (WORD)
 +2 Parameter Descriptor (6 BYTES)
 +8 Return Descriptor (7 BYTES)
 +15 (0Fh) Detail Level (WORD)
 +17 (11h) Receive Buffer Length (WORD)

The 'Function Code' found in 'Parameters' specifies the function
requested. In this case it must be 68h (NetServerEnum2), D7h
(NetServerEnum3) or 00h (NetShareEnum).

The problem arises when the fields 'Max Param Count' and/or 'Max Data
Count' are set to zero (0).

Once the request packet is received by the Windows server, it is handled
by the SRV.SYS driver in kernel mode. At SRV.SYS+08F4h it is determined
that the packet is a SMB_COM_TRANSACTION and a function we arbitrary named
'doSMB_COM_TRANSACTION' (SRV.SYS+D42A) is called where the Transaction
Request portion of the packet is parsed.

Here the 'Max Data Count' and 'Max Param Count' (and all other fields) are
extracted from the packet received, some calculations and sanity checks
are performed to determine the location of the 'Parameters' in the
transaction request packet and the amount of memory needed to store them.
A function is then called at SRV.SYS+DAB0 to allocate a structure in the
heap (BUFFER1 from now on) that will contain data obtained from the
transaction packet and the 'Parameters':

[..]
0000DADB movzx eax, si
0000DADE mov [ebp+var_4], eax
0000DAE1 add eax, 3
0000DAE4 mov ecx, eax
0000DAE6 mov [ebp+var], eax
0000DAE9 mov eax, [ebp+argC_MaxDataCountAdded]
0000DAEC and ecx, 0FFFFFFFCh ; align
0000DAEF cmp eax, 10400h ; the max of the data
with
                                                 ; everything added is
66560
0000DAF4 lea edi, [ecx+eax+98h] ; Calculate the space
                                                    ; needed for the
structure
                                                    ; + the 'Parameters'
0000DAFB mov [ebp+argC_MaxDataCountAdded], edi
0000DAFE ja short loc_1DB22
0000DB00 cmp [ebp+arg_1C], 0
0000DB04 jnz locAllocateHeap
[..]

[..]
0001B806 locAllocateHeap:
0001B806 lea eax, [ebp+1Ch]
0001B809 push eax ; ptr to buffer that will
contain
                                                 ; error code
0001B80A push edi ; Bytes to allocate
(calculated
                                                 ; above at SRV.SYS+DAF4)
0001B80B call myAllocateHeap
0001B810 jmp loc_1DB20
[..]

Later in the processing of the request, at SRV.SYS+33209h another buffer
will be allocated in the heap. This buffer (BUFFER2) will be next to the
one allocated at SRV.SYS+1B806h (BUFFER1).

The problem is that due to the lack of proper checks and miscalculation,
when the 'Max Data Count' and/or 'Max Param Count' are zero, the length of
the first buffer allocated on the heap (BUFFER1) will be insufficient and
the first 8 bytes of the next chunk on the heap (used by the
ntoskrnl!RtlFreeHeap() algorithm) will be overwritten.

When the first buffer allocated is freed by calling ntoskrnl!RtlFreeHeap()
the heap will be in an inconsistent state (due to the corruption of the
chunk's 'control' data, used by the ntoskrnl!RtlFreeHeap() algorithm) and
RtlFreeHeap() will try to access an invalid memory address resulting in
the system crash (Blue Screen).

The actual corruption of the heap occurs as result of a LPC message sent
by SRV.SYS to the Lanman Server Service (implemented in srvsvc.dll,
running in user mode).

At SRV.SYS+33358, an LPC message to the Port '\\XactSrvLpcPort' is sent
(This port is created by srvsvc.dll):

[..]
00033336 push [ebp+arg_0]
00033339 call myImpersonateSecurityContext
0003333E xor esi, esi
00033340 mov [ebp+errorCode], eax
00033343 cmp eax, esi
00033345 jl short loc_43366
00033347 lea eax, [ebp+varReplyMessage]
0003334D push eax ; OUT PPORT_MESSAGE
ReplyMessage
0003334E lea eax, [ebp+varRequestMessage]
00033351 push eax ; IN PPORT_MESSAGE
RequestMessage
00033352 push myPortHandle ; IN HANDLE PortHandle
00033358 call ds:NtRequestWaitReplyPort
0003335E mov [ebp+errorCode], eax
[..]

This message is handled by srvsvc.dll where function to be called is
obtained from a message table, described below as 'PortFuncMsgTable':

[..]
767E88A3
767E88A3 mov [ebp+var_CC], 10h
767E88AC mov [ebp+var_CA], 28h
767E88B5 mov [ebp+var_C8], esi
767E88BB mov eax, [ebp+var_88]
767E88C1 mov [ebp+var_C4], eax
767E88C7 mov eax, [ebp+var_84]
767E88CD mov [ebp+var_C0], eax
767E88D3 mov eax, [ebp+var_80]
767E88D6 mov [ebp+var_BC], eax
767E88DC mov eax, [ebp+var_78]
767E88DF cmp eax, 0Ah
767E88E2 ja Func3
767E88E8 jmp ds:PortFuncMsgTable[eax*4]
[..]

This ends up calling the function at SRVSVC.DLL:767EE136, that receives
the buffer allocated (BUFFER1) in kernel mode by the SRV.SYS driver.

The function then checks again the Parameters of the transaction request,
by calling different functions in xactsrv.dll:

[..]
767EE1B1 push eax
767EE1B2 push ebx
767EE1B3 call pfXsCheckSmbDescriptor ;
XsCheckSMBDescriptor is located in
       ; xactsrv.dll (7568d46f)
767EE1B9 test eax, eax
767EE1BB jnz loc_767EE2A1
[..]

XsCheckSMBDescriptor performs some checks and processing of the Parameters
and Return Descriptor of the SMB Transaction request. Then the function
'XsCaptureParemters' is called to perform further processing:

[..]
767EE2A1 lea eax, [ebp-0D0h]
767EE2A7 push eax
767EE2A8 push dword ptr [ebp-20h] ; ptr to 'BUFFER1'
structure
767EE2AB call pfXsCaptureParameters
767EE2B1 mov [ebp-1Ch], eax
[..]

At xactsrv!7568D2D5 the 5th byte after the end of BUFFER1 is overwritten
with a 0:

[..]
7568D2D5 movzx ecx, ax
7568D2D8 mov [esi], ax
7568D2DB mov edi, [edx+48h]
7568D2DE mov edx, ecx
7568D2E0 xor eax, eax
7568D2E2 shr ecx, 2
7568D2E5 repe stosd
7568D2E7 mov ecx, edx
7568D2E9 and ecx, 3
7568D2EC repe stosb ; here the 5th byte is overwritten
7568D2EE jmp short loc_7568D33D
[..]

After returning from this call, based on the Function Code of the
transaction, the requested function is called in xactsrv.dll
(XsNetServerEnum2, XsNetServerEnum3, or XsNetShareEnum in this case)

[..]
767EE22F mov dword ptr [ebp-4], 2
767EE236 push dword ptr [ebp-0D0h]
767EE23C push dword ptr [ebp-0DCh]
767EE242 push ebx
767EE243 push dword ptr [ebp-1Ch]
767EE246 call dword ptr table_767F2E38[edi] ;
'function' table
[..]

Inside the called function (XsNetServerEnum2 or XsNetServerEnum3) another
function, browser.dll!I_BrowserServerEnumForXactSrv, will be called. The
value returned from this function will later be used to overwrite the
heap. The observed return values that are used to overwrite the heap were
17E6h and 7Ch. It is not evident that these values can be controlled by
the attacker in a reliable way.

[..]
75688823 add eax, 64h
75688826 push eax
75688827 push [ebp+var_38]
7568882A push ebx
7568882B call I_BrowserServerEnumForXactsrv
75688830 mov [edi], ax ; ax contains returned value
        ; this value will be the one
        ; used to overwrite the heap
75688833 test ax, ax
75688836 jz short loc_75688844
[..]

Finally after some more processing the function will return to
srvsvc.dll!767ee24c after executing the function requested
(XsNetServerEnum2, XsNetServerEnum3 or XsNetShareEnum)

Some other processing with the returned number will be done and the
XsSetParameter function will be called. This call will effectively
overwrite the first two bytes after the BUFFER1 structure with the value
returned from the call to browser.dll!I_BrowserServerEnumForXactSrv, and
then the 3rd and 4th byte will be overwritten with 0.

[..]
767EE28C push dword ptr [ebp-0A0h]
767EE292 push edi
767EE293 push dword ptr [ebp-20h]
767EE296 call pfXsSetParameters ; Call to
XsSetParameters
[..]

[..]
XsSetParameters:
7568DB0D
7568DB0D push ebp
7568DB0E mov ebp, esp
7568DB10 push ecx
7568DB11 mov ecx, [ebp+0Ch]
7568DB14 mov eax, [ebp+10h]
7568DB17 push ebx
7568DB18 push esi
7568DB19 mov esi, [ebp+08h]
7568DB1C mov dx, [ecx]
7568DB1F push edi
7568DB20 push 2
7568DB22 mov ebx, [esi+40h] ; ptr to past the end of
BUFFER1
7568DB25 mov [ebp+10h], eax
7568DB28 mov eax, [esi+3Ch]
7568DB2B pop edi
7568DB2C mov [ebx], dx ; overwrite the first two bytes
7568DB2F mov dx, [ecx+2]
7568DB33 add ebx, edi
7568DB35 add eax, edi
7568DB37 mov [ebx], dx ; overwrite the 3th and 4th
byte
[..]

Exploitation of this vulnerability in order to run arbitrary code on the
vulnerable system is not straightforward and our research so far could not
identify a reliable attack scenario other than to perform a denial of
service.

The complexity of exploiting this vulnerability to gain unauthorized
access to a system or plainly run arbitrary code on it resides on the fact
that the attacker can not completely control the bytes used to overwrite
the chunk's 'control' data nor the bytes contained in BUFFER2 (of which
the 'control' data is overwritten).

We do not discard that further research will demonstrate that arbitrary
code execution is possible.

When the attack is performed using the NetShareEnum function, the
corruption of the
heap also occurs in the call to XsSetParameters, but
I_I_BrowserServerEnumForXactsrv is not called, and possible values to
overwrite the chunk 'control' data are more promising in terms of
exploiting the problem, but the lack of complete control of the data of
BUFFER2 again makes it difficult.

Conclusion:
The vulnerabilities described in this advisory can be abused by an
attacker in order to conduct a denial of service attack against the
vulnerable system both remotely and locally using either an active user's
account or logging in using a NULL connection.

Arbitrary execution of code has not been proved but is not discarded as a
possibility.

ADDITIONAL INFORMATION

The information has been provided by
<mailto:core.lists.bugtraq@core-sdi.com> Iván Arce.

========================================

This bulletin is sent to members of the SecuriTeam mailing list.
To unsubscribe from the list, send mail with an empty subject line and body to: list-unsubscribe@securiteam.com
In order to subscribe to the mailing list, simply forward this email to: list-subscribe@securiteam.com

====================
====================

DISCLAIMER:
The information in this bulletin is provided "AS IS" without warranty of any kind.
In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages.



Relevant Pages