1.Description: The nwfs.sys kernel driver distributed with Novell Client 4.91 SP5 IR1 for Windows XP/2003 contains an integer overflow vulnerability in the handling of IOCTL 0x1439EB. Exploitation of this issue allows an attacker to execute arbitrary code within the kernel. An attacker would need local access to a vulnerable computer to exploit this vulnerability. Affected application: Novell Client 4.91 SP5 IR1 for Windows XP/2003 (up-to date). Affected file: nwfs.sys version 4.91.5.8. 2.Vulnerability details: function at 0x000349CC is responsible for dispatching ioctl codes: .text:000349CC ; int __stdcall ioctl_handler(int, PIRP Irp) .text:000349CC ioctl_handler proc near ; DATA XREF: DriverEntry-1CCBo .text:000349CC .text:000349CC var_3C = dword ptr -3Ch .text:000349CC var_38 = dword ptr -38h .text:000349CC var_34 = dword ptr -34h .text:000349CC var_30 = dword ptr -30h .text:000349CC var_2C = dword ptr -2Ch .text:000349CC var_28 = dword ptr -28h .text:000349CC var_24 = dword ptr -24h .text:000349CC var_20 = dword ptr -20h .text:000349CC var_1C = dword ptr -1Ch .text:000349CC ms_exc = CPPEH_RECORD ptr -18h .text:000349CC Irp = dword ptr 0Ch .text:000349CC .text:000349CC push 2Ch .text:000349CE push offset stru_81020 .text:000349D3 call __SEH_prolog .text:000349D8 call ds:KeEnterCriticalRegion .text:000349DE mov ebx, [ebp+Irp] .text:000349E1 mov esi, [ebx+60h] .text:000349E4 mov [ebp+var_1C], esi .text:000349E7 inc dword_8A1E0 .text:000349ED mov eax, [ebx+60h] .text:000349F0 or byte ptr [eax+3], 1 .text:000349F4 mov dword ptr [ebx+18h], 103h .text:000349FB and dword ptr [ebx+1Ch], 0 .text:000349FF call sub_641C0 .text:00034A04 mov edi, eax .text:00034A06 mov [ebp+var_2C], edi .text:00034A09 test edi, edi .text:00034A0B jnz short loc_34A2A [..] .text:00034A2A loc_34A2A: ; CODE XREF: ioctl_handler+3Fj .text:00034A2A mov [edi+0Ch], ebx .text:00034A2D mov eax, [esi+18h] .text:00034A30 mov [edi+10h], eax .text:00034A33 mov eax, [esi+0Ch] .text:00034A36 mov ecx, 14393Bh .text:00034A3B cmp eax, ecx .text:00034A3D ja loc_34E8F [..] .text:000350F1 loc_350F1: ; CODE XREF: ioctl_handler+6D1j .text:000350F1 sub eax, 1439EBh .text:000350F6 jz short loc_3514B [..] .text:0003514B loc_3514B: ; CODE XREF: ioctl_handler+72Aj .text:0003514B push edi .text:0003514C call ioctl_handler_0x1439EB_vuln [..] .text:000112F0 ioctl_handler_0x1439EB_vuln proc near ; CODE XREF: ioctl_handler+780p .text:000112F0 ; sub_46558+694p .text:000112F0 .text:000112F0 var_80 = byte ptr -80h .text:000112F0 var_78 = dword ptr -78h .text:000112F0 var_74 = dword ptr -74h .text:000112F0 var_68 = byte ptr -68h .text:000112F0 var_60 = dword ptr -60h .text:000112F0 var_5C = dword ptr -5Ch .text:000112F0 var_50 = dword ptr -50h .text:000112F0 var_4C = dword ptr -4Ch .text:000112F0 var_48 = dword ptr -48h .text:000112F0 var_44 = dword ptr -44h .text:000112F0 var_40 = dword ptr -40h .text:000112F0 var_3C = dword ptr -3Ch .text:000112F0 var_38 = dword ptr -38h .text:000112F0 var_34 = dword ptr -34h .text:000112F0 var_30 = dword ptr -30h .text:000112F0 var_2C = dword ptr -2Ch .text:000112F0 var_28 = dword ptr -28h .text:000112F0 var_24 = dword ptr -24h .text:000112F0 var_20 = dword ptr -20h .text:000112F0 pMem = byte ptr -1Ch .text:000112F0 ms_exc = CPPEH_RECORD ptr -18h .text:000112F0 arg_0 = dword ptr 8 .text:000112F0 .text:000112F0 push 70h .text:000112F2 push offset stru_7F430 .text:000112F7 call __SEH_prolog .text:000112FC mov eax, [ebp+arg_0] [..] LULZ THANK YOU Novell for leaving such strings: .text:0001140B push dword ptr [eax+0Ch] .text:0001140E push ebx .text:0001140F push offset aNwc_verify_key ; "NWC_VERIFY_KEY_WITHCONN" .text:00011414 push esi .text:00011415 push offset Format ; "[NWFS] VerifyIOCTL EXCEPTION 0x%08X whi"... .text:0001141A call DbgPrint .text:0001141F add esp, 18h [..] .text:00011422 loc_11422: ; CODE XREF: ioctl_handler_0x1439EB_vuln+28j .text:00011422 ; ioctl_handler_0x1439EB_vuln+F0j .text:00011422 or [ebp+ms_exc.disabled], 0FFFFFFFFh .text:00011426 test ebx, ebx .text:00011428 jz loc_114EA .text:0001142E mov [ebp+ms_exc.disabled], 1 .text:00011435 mov eax, [ebx] .text:00011437 mov ecx, [ebx+4] .text:0001143A mov eax, [eax+8] .text:0001143D add eax, [ecx+8] .text:00011440 push eax ; NewIrql .text:00011441 push dword_8A1DC ; int .text:00011447 call Alloc_NonPaged_vuln_proxy [..] .text:00010980 Alloc_NonPaged_vuln_proxy proc near ; CODE XREF: ioctl_handler_0x1439EB_vuln+157p .text:00010980 ; sub_11820+20Dp ... .text:00010980 .text:00010980 nBytes = byte ptr 0Ch .text:00010980 .text:00010980 mov edi, edi .text:00010982 push ebp .text:00010983 mov ebp, esp .text:00010985 push dword ptr [ebp+nBytes] ; nBytes .text:00010988 push 1 ; int .text:0001098A call Alloc_NonPaged_vuln .text:0001098F pop ebp .text:00010990 retn 8 .text:00010990 Alloc_NonPaged_vuln_proxy endp [..] .text:0004EEA6 ; int __stdcall Alloc_NonPaged_vuln(int, UINT nBytes) .text:0004EEA6 Alloc_NonPaged_vuln proc near ; CODE XREF: Alloc_NonPaged_vuln_proxy+Ap .text:0004EEA6 ; sub_10A16+Ap ... .text:0004EEA6 .text:0004EEA6 var_4 = dword ptr -4 .text:0004EEA6 arg_0 = dword ptr 8 .text:0004EEA6 nBytes = dword ptr 0Ch .text:0004EEA6 .text:0004EEA6 mov edi, edi .text:0004EEA8 push ebp .text:0004EEA9 mov ebp, esp .text:0004EEAB push ecx .text:0004EEAC push ebx .text:0004EEAD mov ebx, [ebp+nBytes] .text:0004EEB0 test ebx, ebx .text:0004EEB2 jz loc_4EF5E .text:0004EEB8 mov [ebp+var_4], ebx .text:0004EEBB add ebx, 18h <---- Integer overflow right here! What about 0xffffffe8 value? :P .text:0004EEBE cmp [ebp+arg_0], 3 .text:0004EEC2 ja loc_4EF5E .text:0004EEC8 push esi .text:0004EEC9 push 5346574Eh ; Tag .text:0004EECE push ebx ; NumberOfBytes .text:0004EECF push 0 ; PoolType .text:0004EED1 call ds:ExAllocatePoolWithTag [..] .text:0004EF40 mov ecx, [ebp+var_4] .text:0004EF43 mov edx, ecx .text:0004EF45 add esi, 18h .text:0004EF48 shr ecx, 2 .text:0004EF4B xor eax, eax .text:0004EF4D mov edi, esi .text:0004EF4F rep stosd <--- Pool overflow .text:0004EF51 mov ecx, edx .text:0004EF53 and ecx, 3 .text:0004EF56 rep stosb 3.Exploit - made it by youself! :P