1 / 32

Windows SECURE RING0 DEVELOPMENT

Fermín J. Serna – MSRC Engineering @ Microsoft. Windows SECURE RING0 DEVELOPMENT. Fermín J. Serna – MSRC @ Microsoft. Agenda. Introduction Common mistakes in kernel mode MSRC case history Yes, you will see Windows Kernel Source Code  Detect / Protect QA.

niloufer
Download Presentation

Windows SECURE RING0 DEVELOPMENT

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Fermín J. Serna – MSRC Engineering @ Microsoft Windows SECURE RING0 DEVELOPMENT

  2. Fermín J. Serna – MSRC @ Microsoft Agenda • Introduction • Commonmistakes in kernelmode • MSRC case history • Yes, youwillsee Windows KernelSourceCode • Detect/Protect • QA

  3. Fermín J. Serna – MSRC @ Microsoft Introduction • Who am I? • Security Engineer at MSRC EngineeringReact (former SWI). • Technicalbackground of MSRC forexternallyreportedsecurityissues: MSo8-67, … • HPUX PA-RISC, Solaris SPARC: assembly, shellcode and exploitlover. • Publishedseveraldocs and exploits: Phrack (58-9) HP-UX PA-RISC exploitationtechniqueslong time ago, … • Developer of a PAX implementationon win32 long time ago…

  4. Fermín J. Serna – MSRC @ Microsoft Introduction • Purpose of thetalk • Kernelmodeisnotthatobscure and it shares the similar problemswithusermode • Willdemonstratethiswith real MSRC cases. • Evangelizationonkernelmodesecurityawareness • Providetools and techniquesforkernelmodedevelopers and testers

  5. Fermín J. Serna – MSRC @ Microsoft Introduction • Kernelmode vs usermode (Win32 - x86) • Twoexecutionmodes: privilegedmode and non privilegedone • 2Gb forkernel – 2Gb forusermode (/3GB) • Protectedmode, paging and segmentationprotectskernelspace • Kernelmodeneedstovalidateusermoderequests and their data (untrusted)

  6. Fermín J. Serna – MSRC @ Microsoft Introduction

  7. Fermín J. Serna – MSRC @ Microsoft Introduction • Kernelentrypoints (Win32) • Software interrupts (Sysenter, int 2eh, etc) • Device IO (read, write, IO, etc) • UsermodeCallbacks • Networking • Hardware • Others

  8. Fermín J. Serna – MSRC @ Microsoft Introduction • Entrypointexample: ZwFake_GetMeColorAtPixel(Ulong x, Ulong y, Ulong* buffer) • Whatdoesit do? • Executed in kernelmodewithusermodeparams • Wewillwritetothesupplied buffer • Whatcouldgowrongif buffer pointsto a kernelmodeaddress?

  9. Fermín J. Serna – MSRC @ Microsoft Introduction Request: give me the color at pixel (x,y) and storeit in buffer z KernelSpace Tcpip.sys Driver.sys Win32k.sys Userspace Buffer Z ntdll.dll Kernel32.dll

  10. Fermín J. Serna – MSRC @ Microsoft Introduction Request: give me the color at pixel (x,y) and storeit in buffer z KernelSpace Tcpip.sys Buffer Z Driver.sys Win32k.sys Userspace ntdll.dll Kernel32.dll

  11. Fermín J. Serna – MSRC @ Microsoft Introduction • Whatkernel/drivers should do • Validateallusermode data • ProbeForWrite() • ProbeForRead() • Handlevalidation • Capture data locally in kernelspace • Access usermode data only once. Parallelusermodethreadscouldbechangingthe data. • “Time of Check Time of Use” attacks • Raceconditions

  12. Fermín J. Serna – MSRC @ Microsoft Introduction • ProbeForRead/Write(addr, len,align) • Validatesif a memoryrangeis in usermode • Ifrangeoverlapswithkernelmemorygeneratesanexception • ProbeForWriteprobesallthepagesforWriteaccess. • If ( len == 0 ) continuewith no exception • DuetoLegacycodecompatibility

  13. Fermín J. Serna – MSRC @ Microsoft CommonMistakes • Integeroverflows and oldschoolmistakes • Of course, they do alsoexist in kernelmode void foo(struct bar *x, USHORT len) { USHORT blah; blah=get_actual_counter(); blah+=len; new_entries = ExAllocatePoolWithTag( NonPagedPool,blah*sizeof(struct bar),TAG_NAME); for (USHORT counter=0; counter<get_actual_counter(); counter++) { // Copy old entries } for (USHORT counter=0; counter<len;counter++) { // Copy new entries } blah can overflow size can overflow NULL deref Memorycorruption

  14. Fermín J. Serna – MSRC @ Microsoft CommonMistakes • Trustinguser-supplied pointers • Kernel API, no probing of usermode data • Sameappliesto IOCTL and METHOD_NEITHER void NtUser_giveme_foo(struct bar *x, USHORT len) { for (USHORT counter=0; counter<len;counter++) { // Copy entries to x } } No NULL checkingon X No ProbeForWriteon X No lengthcheck

  15. Fermín J. Serna – MSRC @ Microsoft CommonMistakes • Nulldereferencing (SystemBuffer + more) case IOCTL_FOO_STATS: // METHOD_BUFFERED Stats = Irp->AssociatedIrp.SystemBuffer; Irp->IoStatus.Information = sizeof(*Stats); if (Stats->Version != FOO_STATS_VERSION) { Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; break; } *Stats->data = *FooSt; Usermode Data Derefitwithout NULL checking Ifattackercontrols NULL page….

  16. Fermín J. Serna – MSRC @ Microsoft CommonMistakes • BypassingProbeForRead/Write (zerolen) // lParam and wParam are untrusted DWORDs LARGE_STRING str; try { str.bAnsi = bAnsi; str.MaximumLength = wParam; if (!bAnsi) { str.MaximumLength *= sizeof(WCHAR); } str.Length = 0; str.Buffer = (LPBYTE)lParam; ProbeForWrite((PVOID)str.Buffer, str.MaximumLength,1); } except (StubExceptionHandler(FALSE)) { MSGERROR(0); } [... later write into str.Buffer pointer based on wParam ...] This can overflow and becomezero PFW willsay Ok for a zerolength LateronwewritewParamTchars

  17. Fermín J. Serna – MSRC @ Microsoft CommonMistakes • BypassingProbeForRead/Write (len != usedlen) // Attacker controls OutputBuffer and OutputBufferLength void IOCTL_foo_handler(...) { [...] try { ProbeForWrite(OutputBuffer,OutputBufferLength,sizeof(UCHAR)); RtlCopyMemory(OutputBuffer,context->offset,context->Length ); } except( FOO_EXCEPTION_FILTER(&status) ) { } [...] } Outputbufferlengthcanbezero OutputBuffer can pointtokmode PFW willsayitis OK Wecopybasedonanothersize

  18. Fermín J. Serna – MSRC @ Microsoft CommonMistakes • Casting/Truncation... // lParam and wParam are untrusted DWORDs LARGE_STRING str; try { str.bAnsi = bAnsi; str.MaximumLength = WORD_TRUNCATION(wParam); str.Length = 0; str.Buffer = (LPBYTE)lParam; ProbeForWrite((PVOID)str.Buffer,str.MaximumLength,1); } except (StubExceptionHandler(FALSE)) { MSGERROR(0); } [... later write into str.Buffer pointer based on wParam ...] This can bebecomezero PFW willsay Ok for a zerolength LateronwewritewParamTchars

  19. Fermín J. Serna – MSRC @ Microsoft CommonMistakes • Lack of exceptionhandlingonProbeForRead/Write and data access // lParam and wParam are untrusted DWORDs LARGE_STRING str; str.bAnsi = bAnsi; str.MaximumLength = (ULONG)wParam; str.Length = 0; str.Buffer = (LPBYTE)lParam; ProbeForWrite((PVOID)str.Buffer, str.MaximumLength, 1); *str.Buffer=‘\0’; Weinitialize LARG_STRING PFW can throwanexception Writtingtousermodetoo! Exceptionhandling? bugcheck

  20. Fermín J. Serna – MSRC @ Microsoft CommonMistakes • Trustingusermodestructures (doublefetch) // Attacker controls lParam void win32k_foo_entry_point(...) { // lParam has already passed successfully the ProbeForRead my_struct = (PMY_STRUCT)lParam; if (my_struct ->lpData) { cbCapture = sizeof(MY_STRUCT) + my_struct->cbData; […] if (my_alloc=UserAllocPoolWithQuota(cbCapture,TAG1))!= NULL) { RtlCopyMemory(my_alloc,my_struct->lpData,my_struct->cbData); } } } my_structisalreadyvalidated Butnotcaptured Firstusermodefetch Secondone…

  21. Fermín J. Serna – MSRC @ Microsoft MSRC Cases • MS08-01: IGMP IGMPv3GroupRecord * GetGSIsInRecord(IN IGMPAddr *AddrPtr, IN uint *RecSize) { IGMPSrcAddr *Src, *PrevSrc; IGMPv3GroupRecord *Rec; ushort Count = 0; for (Src=AddrPtr->iga_srclist; Src; Src=Src->isa_next) { if (!IS_SOURCE_ALLOWED(AddrPtr, Src)) continue; if (!Src->isa_csmarked) continue; Count++; } // Allocate record Rec = CTEAllocMemN(RECORD_SIZE(Count,0), 'qICT'); if (Rec == NULL) { *RecSize = 0; return NULL; } Countinitializaed This can overflow 65535 Small allocation Lateron pool overflow

  22. Fermín J. Serna – MSRC @ Microsoft MSRC Cases • MS08-25: Win32k MESSAGECALL(OUTSTRING) { LARGE_STRING str; BEGINRECV_MESSAGECALL(0); try { str.bAnsi = bAnsi; str.MaximumLength = (ULONG)wParam; if (!bAnsi) { str.MaximumLength *= sizeof(WCHAR); } str.Length = 0; str.Buffer = (PVOID)lParam; ProbeForWrite((PVOID)str.Buffer, str.MaximumLength, sizeof(BYTE)); } except (StubExceptionHandler(FALSE)) { MSGERROR(0); } Truncationto 31 bits Alsoanintegeroverflow Length can bezero and PFW Bypass Lateronwehad a RtlCopyMemory

  23. Fermín J. Serna – MSRC @ Microsoft MSRC Cases • MS08-66: AFD.sys try { if (RequestorMode != KernelMode ) { ProbeForWrite (OutputBuffer, OutputBufferLength, sizeof (UCHAR)); RtlCopyMemory( OutputBuffer, (PUCHAR)context+endpoint->Common.VcConnecting.RemoteSocketAddressOffset, endpoint->Common.VcConnecting.RemoteSocketAddressLength ); *Information = endpoint->ContextLength; } except( AFD_EXCEPTION_FILTER (status) ) { ASSERT (NT_ERROR (status)); } Validatewithsuppliedlength Actual usagewithdifferentone Ifkmodeaddr and lengthzero Kernelmemorycorruption

  24. Fermín J. Serna – MSRC @ Microsoft MSRC Cases • MS07-66: ALPC AlpcpIsReplyAllowed( __in PALPC_PORT PortObject,__in PKALPC_MESSAGE Message ) { BOOLEAN Allowed; PALPC_COMMUNICATION_INFO CommunicationInfo; PALPC_PORT OwnerPort; ALPCASSERT_PTR(AlpcpIsLocked(Message) != FALSE, Message); ALPCASSERT_PTR(AlpcpIsCanceled(Message) == FALSE, Message); if (Message->PortQueue != PortObject) { if (Message->PortQueue == NULL) { OwnerPort = AlpcpGetOwnerPortMessage(Message); ALPCASSERT_PTR(OwnerPort != NULL, Message); CommunicationInfo = OwnerPort->CommunicationInfo; Thisfunction can return NULL ASSERT only,notpresent in free build ReadAVfrom NULL page

  25. Fermín J. Serna – MSRC @ Microsoft MSRC Cases • MS08-61: Win32k pcds = (PCOPYDATASTRUCT)lParam; if (pcds->lpData) { cbCapture = sizeof(COPYDATASTRUCT) + pcds->cbData; } else { cbCapture = sizeof(COPYDATASTRUCT); } if (cbCapture && (psms->pvCapture = UserAllocPoolWithQuota (cbCapture, TAG_SMS_CAPTURE)) != NULL) { if (pcds->lpData) { pcdsNew->lpData=(PVOID)((PBYTE)pcdsNew + sizeof(COPYDATASTRUCT)); RtlCopyMemory(pcdsNew->lpData, pcds->lpData, pcds->cbData); } Firstfetchfromusermode Allocationbasedonit Secondfetchfromusermode Copybasedonit

  26. Fermín J. Serna – MSRC @ Microsoft Detect/Protect • Fuzzing: devctl.exe and dc2.exe at the WDK • Devctl.exe: IOCTL fuzzerwrittenbyNeillClift • Dc2.exe: Improvedversion in newest WDK • Lots of switchesfortargetedfuzzing • Itis free, itis simple, use it!

  27. Fermín J. Serna – MSRC @ Microsoft Detect/Protect • DriverVerifier • Part of theOperatingSystem • Dynamicanalysistool • Windows key + R: verifier.exe  • Special pool fordetecting pool overflows and underflows. • Handleverification (Usermode vs kernelmodehandles) • Fuzzingwiththesechecksenablediswise

  28. Fermín J. Serna – MSRC @ Microsoft Detect/Protect • Static Driver Verifier • Compile –time tools (build, scan and check) • Staticdv /rule:* • Staticdv /view • Itis free, itis simple, use it!

  29. Fermín J. Serna – MSRC @ Microsoft Detect/Protect • BinaryStaticAnalysisframeworks • Integeroverflowonallocations • ProbeForRead/Write bypass • METHOD_BUFFERED & SystemBuffer • METHOD_NEITHER & UserBuffer | Type3Inputbuffer • […]

  30. Fermín J. Serna – MSRC @ Microsoft Door-Points • What I hope youshouldgetfromthistalk • Itiseasytomakemistakes in kernelmode • Extra validationneeded • Trickytofind… • Butautomatedtools can helpyou • Fuzz… no really… Fuzz!

  31. Fermín J. Serna – MSRC @ Microsoft Greetings • Thankyouguys! • MSRC/MSEC (former SWI): Bruce Dang, Matt Miller, DamianHasse, Andrew Roths and Thomas Garnier • Non-MS people: Sexy Pandas and MatthieuSuiche

  32. Fermín J. Serna – MSRC @ Microsoft Questions Nowor... fermin [_DOT_] serna [_AT_] microsoft [_DOT_] com Twitter: fjserna

More Related