SMB 0-Day
Posted by Chris Valasek on September 09, 2009 at 5:43 PM EDT.
Monday an unpatched vulnerability was publicly disclosed for Windows Vista and newer Windows operating systems, stemming from problems with SMB2. The issue is getting a lot of attention because a denial of service exploit was distributed. After some further analysis, it’s apparent that it could be leveraged for remote code execution, as has been reported elsewhere.
When an incoming SMB request arrives it is handled by the Smb2ValidateProviderCallback function. After some initial parsing to ensure the request meets certain criteria, a validation routine is called based on a field in the SMB request.
.text:00015379 loc_15379:
.text:00015379 movzx eax, word ptr [esi+0Ch]
.text:0001537D mov eax, _ValidateRoutines[eax*4]
.text:00015384 test eax, eax
.text:00015386 jnz short loc_1538F
.text:00015388 mov eax, 0C0000002h
.text:0001538D jmp short loc_15392
.text:0001538F ; -------------------------------------------------
.text:0001538F
.text:0001538F loc_1538F: :
.text:0001538F push ebx
.text:00015390 call eax ; Smb2ValidateNegotiate(x)
A WORD is moved from your SMB request into EAX. That data is supposed to select between 0 and 18 valid ValidateRoutines, but there is no check to verify that the value of EAX is less than 18. Therefore you can assign a semi-arbitrary value to EAX that is past the function table of legitimate validation routines:
.data:0002A270 _ValidateRoutines
.data:0002A270 dd offset _Smb2ValidateNegotiate@4
.data:0002A274 dd offset _Smb2ValidateSessionSetup@4
.data:0002A278 dd offset _Smb2ValidateLogoff@4
.data:0002A27C dd offset _Smb2ValidateTreeConnect@4
.data:0002A280 dd offset _Smb2ValidateTreeDisconnect@4
.data:0002A284 dd offset _Smb2ValidateCreate@4
.data:0002A288 dd offset _Smb2ValidateClose@4
.data:0002A28C dd offset _Smb2ValidateFlush@4
.data:0002A290 dd offset _Smb2ValidateRead@4
.data:0002A294 dd offset _Smb2ValidateWrite@4
.data:0002A298 dd offset _Smb2ValidateLock@4
.data:0002A29C dd offset _Smb2ValidateIoctl@4
.data:0002A2A0 dd offset _Smb2ValidateCancel@4
.data:0002A2A4 dd offset _Smb2ValidateEcho@4
.data:0002A2A8 dd offset _Smb2ValidateQueryDirectory@4
.data:0002A2AC dd offset _Smb2ValidateChangeNotify@4
.data:0002A2B0 dd offset _Smb2ValidateQueryInfo@4
.data:0002A2B4 dd offset _Smb2ValidateSetInfo@4
.data:0002A2B8 dd offset _Smb2ValidateOplockBreak@4
Let’s revisit the following code:
.text:00015379 loc_15379:
.text:00015379 movzx eax, word ptr [esi+0Ch]
.text:0001537D mov eax, _ValidateRoutines[eax*4]
.text:00015384 test eax, eax
.text:00015386 jnz short loc_1538F
.text:00015388 mov eax, 0C0000002h
.text:0001538D jmp short loc_15392
.text:0001538F ; -------------------------------------------------
.text:0001538F
.text:0001538F loc_1538F: :
.text:0001538F push ebx
.text:00015390 call eax ; Smb2ValidateNegotiate(x)
You can see that the attacker can call an address from _ValidateRoutines to (_ValidateRoutines + (WORD * 4)). This gives the attacker 65,536 possible addresses (assuming DWORD addresses) from which to choose, and the process will execute whatever code is pointed to at that address.
When examining the binary you can see there is a plethora of information in the .data section which could potentially be used as a function pointer. This certainly leaves a lot of code the attacker can jump into that the he or she isn’t supposed to be able to run. While going through all the possible options may take a substantial amount of time, this definitely shows that gaining code execution is not impossible. We suspect that there are many researchers on both sides of the fence who are currently evaluating these 65,536 options in search of one that can lead to total control of the victim host.

