Example: barber

Bochspwn Reloaded: Detecting Kernel Memory Disclosure …

Bochspwn ReloadedDetecting Kernel Memory Disclosure with x86 Emulation and Taint TrackingMateusz j00ru JurczykREcon2017, MontrealAlternative title (cheers Alex Ionescu!) Memory Disclosure Alternative titleKERNELBLEEDA genda User Kernel communication pitfalls in modern operating systems Introduction to Bochspwn reloaded Detecting Kernel information Disclosure with software x86 emulation Approaches, results and exploitation Microsoft windows Linux Future work and conclusionsBio Project Zero @ Google CTF Player @ Dragon Sector Low-level security researcher with interest in all sorts of vulnerability research and software exploitation. @j00ruUser Kernel communicationOS design fundamentals User applications run independently of other programs / the Kernel . Whenever they want to interact with the system, they call into the Kernel .

•One real-life example is a Windows kernel exploit found in the HackingTeam dump in July 2015 (CVE-2015-2433, MS15-080). •Pool memory disclosure leaking base address of win32k.sys.

Tags:

  Memory, Windows, Disclosures, Detecting, Kernel, Reloaded, Windows kernel, Bochspwn reloaded, Bochspwn, Detecting kernel memory disclosure

Information

Domain:

Source:

Link to this page:

Please notify us if you found a problem with this document:

Other abuse

Transcription of Bochspwn Reloaded: Detecting Kernel Memory Disclosure …

1 Bochspwn ReloadedDetecting Kernel Memory Disclosure with x86 Emulation and Taint TrackingMateusz j00ru JurczykREcon2017, MontrealAlternative title (cheers Alex Ionescu!) Memory Disclosure Alternative titleKERNELBLEEDA genda User Kernel communication pitfalls in modern operating systems Introduction to Bochspwn reloaded Detecting Kernel information Disclosure with software x86 emulation Approaches, results and exploitation Microsoft windows Linux Future work and conclusionsBio Project Zero @ Google CTF Player @ Dragon Sector Low-level security researcher with interest in all sorts of vulnerability research and software exploitation. @j00ruUser Kernel communicationOS design fundamentals User applications run independently of other programs / the Kernel . Whenever they want to interact with the system, they call into the Kernel .

2 Ring-3 Memory is the i/o data exchange channel. Also registers to a small of a system callUser-mode ProgramShared Memory (user-mode)System KernelWrite input dataInvoke system callRead input dataWrite output dataReturn to user spaceRead output dataSyscall logicLife of a system callUser-mode ProgramShared Memory (user-mode)System KernelWrite input dataInvoke system callRead input dataWrite output dataReturn to user spaceRead output dataSyscall logicIn a perfect Within the scope of a single system call, each Memory unit from at most once, then .. to at most once, securely, only with data intended for reality (double fetches)Read from at most once, securely. Subject of the original Bochspwnstudy in 2013 with Gynvael Coldwind. Possible violation: double(or multiple) fetches, may allow race conditions to break code assumptions buffer overflows, write-what-whereconditions, arbitrary reads, other badness.

3 Dozens (40+) vulnerabilities reported and fixed in windows . A few more just recently (CVE-2017-0058, CVE-2017-0175). Kernel double fetchesIn reality (unprotected accesses)Read from/written to at most once, securely. The Kernel can almost never know if a user pointer is valid before actually operating on it. All accesses must be guarded with try/except blocks. This is well documented and understood, Failure to set up exception handling unhandled exception system crash. Local authenticated DoS condition only, not fixed in bulletins by handler recordstruct_EH3_EXCEPTION_REGISTRATION{ struct_EH3_EXCEPTION_REGISTRATION *Next;PVOIDE xceptionHandler;PSCOPETABLE_ENTRY ScopeTable;DWORDTryLevel;};Microsoft C/C++ Compiler exception handlingPAGE:00671CF3mov [ebp+ ], 1 PAGE:00671 CFAmov eax, [ebp+var_2C]PAGE:00671 CFDmov ecx, [ebp+arg_14]PAGE:00671D00mov [ecx], eaxPAGE:00671D02mov [ebp+ ], 0 FFFFFFFEhException handler #1 activeException handler disabledWrite to user memorySEH chains on the stacknt!

4 SeCaptureSecurityDescriptornt!ObpCapture ObjectCreateInformationnt!ObCreateObject nt!AlpcpCreateConnectionPortnt!NtAlpcCre atePortnt!KiSystemServicePostCallTryLeve l=1 TryLevel=0 TryLevel=0xFFFFFFFEfs:[0] If there are no positive TryLevel in the SEH chain at the time of a user-mode Memory access, it may be used to trigger a bugs found and documentedIn reality (PreviousMode)Read from/written to at most once, securely. There is a global variable in windows called PreviousMode. Indicates if the current Kernel service was invoked from user-mode (UserMode) or the Kernel (KernelMode). Accesses to user-mode Memory while PreviousMode=KernelModecan indicate bugs. Kernel code may trust data/pointers that should not be reality (double writes)Written to at most once, securely, .. Why would the Kernel write to a specific address more than once?

5 Code not realizing it s operating on user pointer and using it for temporary storage? What is stored in Memory before the final write? A normal synchronous user-mode client would never see that data. May indicate some strange/fishy behavior for follow-up reality (read-after-write)Read from [..] thenwritten to [..] Reading from user-space after already having written to it. Again, why? Kernel code mistreating pointer as trusted / exclusive? What happens if we change it in between? Does the function make any assumptions? Another good indicator of interesting or sensitive areas of reality (other heuristics) User-mode accesses with very deep callstacks. Such reads/writes should mostly occur in top-level syscall handlers. The more nested the callstack, the less the code expects to be operating on ring-3 Memory .

6 User-mode accesses with the first enabled exception handler very high up the callstack. Indicator of very broad try/except blocks. Jumping across a number of functions back to the exception handler may leave dangling state in any of them. Listing all user-mode accesses in general. Enumerating new attack surface. Potentially useful in aiding other methods of bughunting, static subject of this talkWritten to at most once, securely,only with data intended for user-modeWriting data to ring-3 System calls Almost every single one on any system. IOCTLs A special case of syscalls, but often have dedicated output mechanisms. User-mode callbacks Specific to the graphical subsystem on windows . Exception handling Building exception records on the user-mode easy problem primitive typesNTSTATUS NtMultiplyByTwo(DWORDI nputValue,LPDWORDO utputPointer){DWORDO utputValue;if(InputValue !)}

7 =0){OutputValue =InputValue *2;}*OutputPointer =OutputValue;returnSTATUS_SUCCESS;}Unini tialized if InputValue == 0 The easy problem primitive types Disclosure of uninitialized data via basic types can and will occur, but: is not a trivial bug for developers to make, compilers will often warn about instances of such issues, leaks only a limited amount of data at once (max 4 or 8 bytes on x86), may be detected during development or testing, since they can be functional bugs. Not an inherent problem to Kernel hard problem structures and unionstypedefstruct_SYSCALL_OUTPUT {DWORDSum;DWORDP roduct;DWORDR eserved;}SYSCALL_OUTPUT,*PSYSCALL_OUTPUT ;NTSTATUS NtArithOperations(DWORDI nputValue,PSYSCALL_OUTPUT OutputPointer){SYSCALL_OUTPUT OutputStruct; =InputValue +2; =InputValue *2;RtlCopyMemory(OutputPointer,&OutputSt ruct,sizeof(SYSCALL_OUTPUT));returnSTATU S_SUCCESS;}Never initialized because reserved The hard problem structures and unionstypedefunion_SYSCALL_OUTPUT {DWORDSum;QWORD LargeSum;}SYSCALL_OUTPUT,*PSYSCALL_OUTPU T;NTSTATUS NtSmallSum(DWORDI nputValue,PSYSCALL_OUTPUT OutputPointer){SYSCALL_OUTPUT OutputUnion; =InputValue +2;RtlCopyMemory(OutputPointer,&OutputUn ion,sizeof(SYSCALL_OUTPUT));returnSTATUS _SUCCESS;}3B 05 00 00?

8 ? ?? ?? ??SumLargeSumHigh 32 bits uninitialized because never usedThe hard problem structures and unionstypedefstruct_SYSCALL_OUTPUT {DWORDSum;QWORD LargeSum;}SYSCALL_OUTPUT,*PSYSCALL_OUTPU T;NTSTATUS NtSmallSum(DWORDI nputValue,PSYSCALL_OUTPUT OutputPointer){SYSCALL_OUTPUT OutputStruct; =InputValue +2; =0;RtlCopyMemory(OutputPointer,&OutputSt ruct,sizeof(SYSCALL_OUTPUT));returnSTATU S_SUCCESS;}3B 05 00 0000 00 00 00 00 00 00 00 SumPaddingLargeSum?? ?? ?? ??Uninitialized structure alignmentThe hard problem structures and unions Structures and unions are almost always copied in Memory entirely. With many fields, it s easy to forget to set some of them. or they could be uninitialized by design. Unions introduce holes for data types of different sizes. Compilers introduce padding holes to align fields in Memory properly.

9 Compilers have little insight into structures (essentially data blobs): dynamically allocated from heap / pools. copied in Memory with memcpy() ?? ?? ?? ?? ??The hard problem fixed-size arraysNTSTATUS NtGetSystemPath(PCHARO utputPath){CHARS ystemPath[MAX_PATH]="C:\\ windows \\System 32";RtlCopyMemory(OutputPath,SystemPath, sizeof(SystemPath));returnSTATUS_SUCCESS ;}?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ???? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ???? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??43 3A 5C 57 69 6E 64 6F 77 73 5C 53 79 73 74 65 6D 33 32 00 Uninitialized unused region of arrayThe hard problem fixed-size arrays Many instances of long fixed-size buffers used in user Kernel data exchange.

10 Paths, names, identifiers etc. While container size is fixed, the content length is usually variable, and most storage ends up unused. Frequently part of structures, which makes it even harder to only copy the relevant part to user-mode. May disclose huge continuous portions of uninitialized Memory at hard problem arbitrary request sizesNTSTATUS NtMagicValues(LPDWORDO utputPointer,DWORDO utputLength){if(OutputLength <3*sizeof(DWORD)){returnSTATUS_BUFFER_TO O_SMALL;}LPDWORDK ernelBuffer =Allocate(OutputLength);KernelBuffer[0]= 0xdeadbeef;KernelBuffer[1]=0xbadc0ffe;Ke rnelBuffer[2]=0xcafed00d;RtlCopyMemory(O utputPointer,KernelBuffer,OutputLength); Free(KernelBuffer);returnSTATUS_SUCCESS; }EF BE AD DEFE 0F DC BA0D D0 FE CA?? ?? ?? ???? ?? ?? ???? ?? ?? ???? ?? ?? ???? ?? ?? ???? ?? ?? ??Uninitialized data in reduntant array entriesThe hard problem arbitrary request sizes Common scheme in windows making allocations with user-controlled size and passing them back fully regardless of the amount of relevant data inside.


Related search queries