 Fy fawr, rydw i'n dweud, rydw i ddim yn bwysig, James a Georgie. Rydw i, wrth gwrs, i'n James a mae'n Georgie. Felly, ychydig ychydig. Rydw i'n dweud ar y ffasrwch ar gyfer yw'r cynnwys, yw'r architektur, rwy'n gwybod ar y cyffredinol, fel yw'r cynnwys ar gyfer yw'r cynnwys. Rydw i'n dweud ar gyfer y cyffredinol, ac mae'r sylfaenau cyfrifiadau, yn ymddangos ar gyfer y dyfodol, ac mae'n gofyn ar gael y gyrdd mwy o'r mwy o'r hyn. Yn oedd yn bwysig, ydych chi'n gweithio ym Morgfaenau, gyda'r Gweithes Cynllun gyda'r gweithiau. Yn ddigon o'r Gweithes Cynllun gyda'r gweithiau, gallwn i'n mynd i'r gweithio, felly eich gweithio ym Gweithes Cynllun gyda'r Gweithes Cynllun gyda'r gweithes Cyllun. Gweithes Cynllun gyda'r Gweithes Cynllun, Pretty important nowadays for things like privesque. Also, at NWR, we have a bit of a friendly and internal competition going on, so Nils presented on his version of his Windows Kernel Cards Red T2, obviously, we're trying to beat the number of bugs that he got in his version. Obviously, we're primarily here to try and improve general-prone system security. Initially and most of our research has been focused on Windows, Windows 7, ond we've actually ported the ffuzzer to run on OSX and QNX, and we're looking to start running it properly over the next few months and trying to find some bugs in those OSs as well. So, how hard can it be? If you look over at Twitter, it would appear everyone has Win32K Oday. And so do we. So about a month ago, we did a run. Purely a test run to make sure the ffuzzer was pretty stable. So, as you can see, 16bm, just 48 hours. We got 65 crashes, 13 of those you need. Which, yeah, I didn't think it was too bad, 13 Oday's in Win7. Okay, cool. As it turns out though, we weren't being particularly effective with our ffuzzing. So, for those that don't know, there's a number of syscles in Win7 that are simply just sleeps for all the intensive purposes. So, we got the one there, NT delay execution. So, we managed to find that one, blacklisted, and actually, surprise, surprise, the ffuzzer was a lot more effective. So, we ran it again last week. We haven't triaged all the crashes, which is why we've not spoken in the slides, but we ended up with around 150 crashes and 40 of those were unique. In the end, actually, we crashed our database. We were pushing all these crashes too because it ran out of space for it. So, that seems pretty cool. We are going to release the framework for the ffuzzer. So, the core will be released, but we're not going to release any OS-specific stuff. But throughout the talk, we're going to go through how you would write the OS-specific stuff and give you some examples so you can go away and ffuz the OSes yourself. It's worth bearing in mind when you look at the code that were hackers, not developers. It's pretty dirty in places. So, yeah, bear that in mind. Our sort of test is does it compile great? It probably works it. So, the architecture. Everything is nicely decoupled. So, you've got in there the center of the framework core, which is basically what runs everything on the outside there, which is the OS-specific stuff. Originally, we deved this up in Python, but we've completely rewritten it in C. It's much more efficient, significantly faster, and seems to be finding a lot more bugs for us. So, the first part is the OS API knowledge base. All this is is the OS-specific API that is used by applications to interface with services provided by the OS. So, this is the things devs do to, you know, do things with graphics or interactive devices or do networking, et cetera, et cetera. Many of these will wrap system calls. We'll provide two examples of how we've deved these for Windows and OS X later on in the talk, but we won't be releasing all of our ones. The next part, the next major part of the OS-specific stuff is the system calls. So, system calls are a low-level method for user space to kernel space communications. These have to be implemented per architecture and operating system. So, that's fine for open source systems, you know, OS X or any NIC space system. These tend to be open source. For Windows, it's a little bit more difficult. You have to reverse engineer these ones out or rely on other sources, maybe React OS or something like that. At the bottom there, you can see what a syscall looks like internally to the fuzzer. So, we just have a syscall ID, the arguments for that syscall and then just a return data type if the syscall provides a return. Also, we have a number of fuzzed values. So, there you can just see the fuzzed values you can grab internally from the fuzzer. We use the words fuzzed, but what we don't necessarily mean fuzzed, actually. So, really, we actually want the library calls and syscalls to work, and to get these to work, we actually have to return proper values. So, whilst we occasionally return a properly fuzzed value, most of the time you'll return a normal value, they're going to ensure that the library call and system call works. Yeah. So, the next part is the object store. The object store is used to maintain state across a fuzzing run and it stores OS-specific objects of interest. So, currently, this is handles in windows and file descriptors in NIC systems. It's implemented as just a global array of structures. It's deterministically populated by the fuzzer, and this is quite important for when you want to reproduce crashes. If this wasn't deterministic, then obviously we'd just never be able to reproduce any crashes we found. It's quite easy to retrieve, update, and then certainly objects into the object store. Okay. The next bit is the helper functions. So, helper functions, we use these for things like library calls that require a struct. It works in pretty much the same way as grabbing a fuzzed value. So, if you want to call for a struct for a library call, you make a call to the helper function and it will return you a struct that should work fine in the library call. So, logging. This is actually quite difficult in kernel fuzzing when you keep hitting crashes. So, initially, we didn't have high hopes for the fuzzer. So, all we did was log a PRNG seed. As you might guess, as a fuzzer, we make heavy use of the round function. So, if we can just seed this again, we'll always get a same run again, which makes reproducing quite easy. A bit of an issue, though, is it doesn't generate a standalone test case, which is ultimately where we want to get to. So, what we've moved on to doing is logging C statements. So, our log files are actually complete source files. And all we do is copy and paste these into a template. There are some issues with this. So, occasionally, if we get a B-sod, we'll find that actually the OS hasn't flushed the right to the file before it's B-sodded in the Windows instance. So, we miss out on, let's say, the last call. As a workaround, what we're doing is we're usually able to grab the stack trace and the arguments and everything else and figure out what it was doing. What we're looking towards doing in the future as well is maybe using something like logging over a socket or something like that, which we're hoping will work a little bit better. As you might guess, this is incredibly tedious. So, this is an example of our logging from a library call. What we do is we grab a variable ID to tag on to the end of a variable, and then we assign that variable and call a function. As you can see at the bottom, we log the function call before calling the function in the father to try and ensure that we log the crash before it actually crashes. So, crash detection. There's actually two methods we tried with this. So, the first way we tried was just attaching a kernel debugger while we were executing the fuzzr. Obviously, it requires one or more debugger processes, which slows execution. So, you can either have on the host debugging the VMs or a VM debugging another VM. But the plus point is we instantly analyse any crashes we find. The other option is unattended execution, which is what we're working on at the moment. And this is just letting the OS handle the crash on its own. Much faster execution, and we can run more VMs as well, and we have less wasted CPU cycles. We recover and analyse the crashes upon reboot. Another way we've been looking at, actually, is using hypervisor logs. So, for example, VM where we'll actually log when a host has crashed. And there's some information in there that's actually quite useful. So, this is the way the crash detection story works. When we reboot the box, the first thing we'll do is try and search for a memory dump file. So, this is quite specific to Windows. If we find a memory dump file, we'll match that up with a log file. So, there should only be one log file on the disk, which is the one that caused the crash. If we get that memory dump file, what we do at the moment is under WinBag, bang, analyse, and just grab those details out. And then the three of them, we timestamp and just archive them all off. So, with a number of VMs, so our ultimate goal is to run this across hundreds of VMs, is we need some form of the fuzzard to push this into a central database. So, those three files I just described are actually pushed into a CouchDB database that we just have sat in AWS. This is really useful for us because it means we can actually do de-duplication across all the VMs. So, all we do is hash the stack. If we've seen that hash before, we push the files and increment a counter. If we haven't, then we push the files out into a CouchDB. It also means we can do some other categorisation stuff. So, doing stuff like type of AV, 14IP, bug check ID, et cetera. Closer to the mic. Okay, so that's the overall architecture for the fuzzard. Sound pleasure? Right, yes. So, that was the overall architecture. So, this is what a fuzzing run looks like. The first thing we do is we have a little bootstrap script that we run to prepare a VM for fuzzing. It's just a really simple Python script that installs everything that's required and just fine-tunes the system. So, we'll go through what the windows one of that looks like later on in the talk. We then launch a second Python script, which is a wrapper around the core fuzzard, but what that one does is go away and collects the memory dumps and submits it to the database if it finds them, et cetera, et cetera, as I just said. We then launch the fuzzard binary, and the first thing we do is populate that object store. So, we generate a bunch of valid handles or file descriptors that we can then use for library and system calls straight away. Okay, so then for a predefined number of iterations, we pick up either a library or system call. So, we'll go away, figure out what the arguments are, and then grab the fuzz value, fuzzstrap, or an object from the object store. And then we invoke that call. We check to make sure it's succeeded, and if it gives us a value back that's useful later on, we'll pop that back into the object store. So, you know, library calls or system calls may return a hand or a file descriptor or something similar. We want to keep holding that value and use it later on. At the end, if we didn't get a crash, all we do is just clean up all our temporary files, remove the logs, and just try and revert back to a clean state. Now, currently, all we do is reboot the box. So, this should mostly give us a clean state to work from from the next fuzzing run. Obviously, we can't just start the fuzzer again because if we have done something in a previous fuzzer run that we haven't logged, it's impossible to reproduce that test crash, and it's useless to us. We're actually also looking at how we can possibly revert back to a VM snapshot, as this will guarantee a clean state to start from. A few caveats to be aware of if you're going to take this framework and use it yourselves. We found a number of bugs in the hypervisors, which has meant we haven't placed this up in the crowd. I'm pretty sure people like Amazon are going to get really annoyed with us if we start crashing their hypervisors. So, what we're looking at doing is running it under QEMU, which is a bit inception-y, but should hopefully work. You also need to look into things like... We're also looking into things on how to protect the fuzzer from itself. So, on a number of occasions, somehow the fuzzer has managed to get a handle to itself and kill itself, which is kind of irritating. So, what we're trying to move on to is a method of how we monitor the host that's fuzzing, monitor the guest story from the host. So, if the fuzzer has killed itself or we've hit another sleep or done something else stupid, we can detect that and then start the fuzzer off again. Cool. So, I'm actually going to hand over to Georgie, who's going to go through Windows case study. So, as James already mentioned, we initially started with the idea of developing a Windows kind of fuzzer. And these actually remain our focus, despite of repurposing the fuzzer for OS agnostic operations. So, the second half of the talk is dedicated on getting the fuzzer working efficiently on Windows and basically writing all of these custom modules for Windows operating systems. So, all of these operating system tweaks and object store implementation details that you need to consider when you take the framework and you want to basically use it for fuzzing Windows. I'll be going through several examples for each one of these bullet points. So, basically examples on how we implemented our object store, some examples on what our collection of system calls looks like in Windows, and basically some examples on the wrappers for the library course that we have developed. I'll be ending this with basically what's the process of bootstrapping the Windows VM before we actually start fuzzing. So, the attack surface we decided to focus on is the Win32K subsystem, a pretty well-known attack surface in Windows operating system. This subsystem implements mainly three components, the window manager responsible for desktops, Windows menus, toolbars, the general user interface element, and the graphics device interface also known as GDI, which is in charge of visualisation on the screen, changing colours and basically just general graphics. Win32K.cs also implements some wrappers for direct X calls, and this is not something we have looked at until now. And this is probably not something we'll consider in the future. There is counter components in user land in terms of user mode libraries, a bunch of DLLs provided for application developers to actually interface with the subsystem. So, if you're an application developer, you wouldn't issue a syscall to the Win32K.cs kernel mode driver. You would be going on SDN and looking at how you interface with this kernel mode driver using some library calls that will eventually wrap into a system call. In the Windows operating system, an object is basically a data structure representing some sort of system resource, and this can be anything from a file, process, window, menu, et cetera. There is roughly three types, main types of objects in the Windows operating system, user objects, GDI objects and kernel objects. User objects are implemented to support the window manager. Obviously, GDI objects are implemented to basically manage the graphic device interface, and kernel objects are basically there to implement basic operations in the kernel space, such as process management, memory management, IPC communication, et cetera. One important thing to realise when we talk about objects is that when an application wants to manipulate an object, when an application wants to access an object, it needs to acquire a handle to that object. So if you want to do something with any of the system resources, you need a handle to each one of them in order to basically interface with them. And this is how handles are defined, object handles are defined in the Windows SDK on a really, really low level. They're just basically void pointers managed by the operating system. Now, the implementation details are hidden from the application developer, and the application developer shouldn't really care about how these handles are implemented. And this is just here for a reference. Furthermore, numerous aliases, aliases are defined for more or less any system resource available on the operating system. So this is a snippet from winddeath.h. Head of file from the Windows SDK where a bunch of these declarations actually happen. There's declaration for a handle to a window, declaration for a handle to a bitmap, et cetera. So each one of these system resources will have a sort of specific handle associated, a handle type associated with it. So knowing and realising how fundamental object handles are in the Windows world, it comes as no surprise that we actually decided to preserve object handles in our object store. The object store implementation itself is really straightforward at the moment. It's just a globally accessible array of 120 elements where we just preserve a bunch of handles to numerous system resources. Handles are retrieved from this object store when we need a handle to be passed as an argument to a system or a library call. And should a system or a library call return successfully another handle, we consider this handle and we push it back to the object store. Sorry. If we start running out of, let's say, space in our object store, in this case it's a fixed value of 128, let's say we start running out of slots in this array, we basically start overriding some of the handles from the object store, we basically throw out the oldest handles and we repopulate the object store with some new ones. One more thing to basically notice is the BH Handle struct. The BH Handle struct is our internal representation of a handle. It has two fields, which is the handle itself, as well as the index of the handle in the object store. So handles will be changing values per run. So basically if we grab a handle to a particular window in one run, this handle will have one value. If we grab a handle to an identical window in a second run, this handle will have a different value. So how we grab the same handle twice why basically referring to the handle, not by its value but by its index in the object store. We have implemented a number of functions to interface with the object store I'm talking about. The first one is basically there to bootstrap the object store, populate the object store with some handles before we even start fuzzing so we can actually use some handles as arguments for library and system calls. The second one is the function getRandomHandle. This function will basically look up the store and randomly pick up a handle from it. It will then wrap the handle in a BH handle struct which helps us successfully log the location of the handle in the object store when we issue logging statements. We have another function for querying the object store. This one is getSpecificHandle. This one takes one argument which is basically the index of the handle we want to extract three from the object store. We also have a function for inserting handles back to the object store. Again, should a library call return successfully a handle which push it back to the object store. For populating the knowledge base of system calls, well basically for the majority of them we had to reverse engineer them. We started with mainly system calls implemented in the Win32 case of system. But there is one thing. When I say reverse engineering I don't really mean reversing the logic of the system call itself or how the system call is implemented under the hood. The only details we're interested in are basically the system call ID and the number of arguments for the system call and the data type for each one of these arguments. Optionally, again, the return type for the system call. For the majority of the system calls you have to do some reverse engineering. For some of them you may also refer to ReactOS but this is not necessarily identical to the Windows revision you're working on. To implement the Cisco invocation itself we had to write some assembly snippets and these are specific to both the operating system and the architecture. A little bit more about the assembly snippets in just a second. This is what an extract from our collection of system call looks like. James already mentioned what our internal representation of a system call looks like, the Cisco struct. The Cisco struct has got three fields. The first one is the system call ID. The second one is an array of data types for each one of the arguments consumed by the system call and the third and optional field is basically whether the system call returns any data type we may be potentially interested in. The system call invocation again is implemented per architecture and per operating system. We have what we call system call invocation template. The prototype for the template is the same across the architectures and this is the code with the name buccan underscore Cisco. This template function takes 33 arguments at the moment. The first one being the Cisco ID and the second, basically the rest of these 32 arguments are arguments for the system call itself. Now obviously not every system call would be taking 32 arguments or I don't even know if there is any system call taking 32 arguments at all. The reason we did a fixed number of arguments is because we didn't want to implement a function with a variable number of arguments sort of print that like style. So what we do at the moment is the system call ID as the first argument for this function. We populate the first arguments with the actual data that should be passed to the system call and we just pat the rest of the 32 arguments with some dummy data. Then buccan Cisco is in charge of setting the registers for the invocation of the system call. Pushing each one of these 32 arguments on the stack and then making transition in Kerneland. Once we are in Kerneland the system call is in charge of basically dispatching the request. Taking care of each one and processing each one of the arguments that are actually expected by the system call. The system call will then simply ignore the rest of the 32 arguments on the stack. The system call will eventually return back to the buccan Cisco wrapper. Buccan Cisco wrapper will clean up the stack and return to the main ffuzzing loop. This is just a general reminder on how system call invocation works on Windows. There are six platforms we have arguments pushed on the stack in a reverse order. We have EAX set to the system call ID and then a call is made to the KI fast system call function. Now there is a caveat. This is the case until Windows 7 which is the operating system we have been mostly focused on. I think in Windows 8 and Windows 10 the KI fast system call has been basically inlined in the code. 64, the first four arguments are set in registers. These are RCX, RDX, R8 and R9. If there's any additional arguments that are pushed on the stack then RAX is set to the system call ID and the CPU instructions is made to basically force transition into kernel space. So much for system calls. Now several examples on how to implement OSAPI Knowledge Base. The OSAPI Knowledge Base, the information that we need for it is publicly available on MSDN. These are basically the library calls that application developers are expected to be using when making requests for the operating system. The OSAPI calls Knowledge Base is implemented as one huge array of function pointers to each one of the library call wrappers that we have implemented. I think until a few days ago we had about 500 library call wrappers. So basically 500 functions from GDI32.dll, user32.dll and some other user mod components. As you can imagine this is a really tedious process of implementing wrappers for each one of these. We looked at automating this by basically crawling MSDN, collecting function prototypes and turning these prototypes into library call wrappers in a more or less automated way. But unfortunately we felt miserably with that and we were looking forward to improving our approach. But at the moment, again, each one of these are implemented strictly manually. I'm going to give a few examples now. This is the destroyed current function from MSDN. This function takes no arguments and returns a boolean value. And the wrapper for this call is really simple, really straightforward. Basically we look the call that we are about to make and we make the actual call. That's literally it. So in the log file we basically end up with the exactly same C statement that we are making in our ffuzzer. Something a bit more interesting is the following one destroyed cursor. On the top you have the prototype from MSDN. This one takes a single argument. This argument is basically a handle to a cursor object. And this function returns a boolean again. So what we do in our wrapper we declare the handle but not as a handle we declare it as a BH handle struct that wraps the handle itself as well as the index. We generate a globally unique variable ID that will be appended to the variable name when we make a logging statement. We then log the declaration for the handle while appending the variable ID to the end of the name of the function. We proceed by grabbing a random handle from the object store and assigning it to the handle that we are going to pass to the library call function. Then we log the handle but we log the handle by its index rather than by its actual value. James mentioned this but the object store at any point of the first run is populated in a deterministic way at least in theory. So if we are up to a point where we know the object store has certain handles we can refer to each one of these handles by its index and it should be the case of getting the same handles that we got the last time with the same seed. The last thing we do is basically log the final call that we are about to make. This is the actual call the actual library call and we log this with the respective variables while again appending the variable ID at the end of them. The last thing is just simply make the call. Something a bit more interesting so for example this example demonstrates how to use the helper functions. The helper functions are functions that will generate a valid struct, a window specific struct that is consumed by a library or a system call and I'll be talking about the helper functions in just a bit. But basically this is a function taking two arguments, a handle to a device context and a color type window type. So we start with the same thing again, we declare the variables that we are going to use within the wrapper we generate the variable ID again this will be globally unique across the run we log the handle again notice that we log the handle as a handle not as a BH handle we basically hide the implementation details for a BH handle when it comes to the reproducer test case we drop a random handle and assign it to our variable. The next thing is log the handlebyte index and the next thing is the interesting bit where we actually make a call to a helper function this one is getColorF and each one of the helper functions takes a single argument which is the variable ID so getColorF will basically hide the details for us but it will populate with mostly valid data again this struct that can later on be used by our library call and again the last thing is log the statement, log the call that we are about to make and make the actual call and now a bit more about the helper functions there is just a endless number of custom structs in the windows operating system and they are expected by a number of library calls and system calls and this is where the helper functions come basically for each one of these well obviously we cannot implement for each one of them but for the most common ones consumed by the winter d2k system and library calls we have implemented helper functions so basically we have helper functions for returning rectangles, points, sizes windows etc and again these are mostly valid and they shouldn't really be way too malformed at the bottom of the slide you can basically a snippet from the list of helper functions we have implemented again the helper function will return a valid struct, the naming convention is get underscore name for the struct and the single argument that will be consumed is the global unique variable ID this one is really obvious and really easy to implement because this is just a type of the word in windows so basically we start by declaring the color ref variable we log the declaration by appending the variable ID to the name of the variable we initialize the variable by calling get underscore first underscore un32 this will basically grab unsigned integer from the first value store assign it to cr and then we log this value as it was assigned and return the struct to the caller which will be then passing this struct to the library call something a bit more interesting so for example this one is helper function for returning rectangle rectangle is a struct with four fields each one of them type long so what we do is basically pretty much the same apart from initializing each one of the fields separately and for each one of these initializations we log in our log file and in case study ffuzzing the windows VM what do we need to do in order to basically get a basically the VM in a decent state for our ffuzzer to run in an optimal way we start by installing Python 3.5 and then we have a bootstrap script that will set up the VM and do some general OS tweaks this includes installing wind debugger installing the Python module for couchDB communication in order to submit our crashes to the centralized database we perform some minor tweaks in the registry including disabling error reporting disabling updates etc we enable kernel memory dumps basically this is where we get the information about the crash we enable special pool for the module that we're ffuzzing the for the kernel mode driver that we're ffuzzing which in this case is wind32k.sys a special pool is basically the equivalent of page keep in kernel land and a special pool will make it a lot easier to detect use after free vones, double free and general pool corruptions as well so it's very important to enable this and the last thing and obvious thing is to schedule the ffuzzer control script to start on logon and reboot the system upon rebooting the system the ffuzzer kicks in the first thing to do is look up the location for where we store the memory dumps so if there is a memory dump we wrap the memory dump we run bang analyze using katiexie we store this in a log file that we will later on be submitted we checked for a leftover ffuzzer lock from from a previous run and we basically assume the fact that this is the log file that caused the last besword we bundle everything together which is basically the ffuzzer lock the memory dump file and the output from bang analyze and we submit all of these all together to couchdb where couchdb will basically in couchdb we will be able to do some triaging and querying based on the crash there was pretty much about it when it comes to windows again we have done some stuff on macOSX and QNX QNX just to prove the concept that it actually works and the ffuzzer is more or less platform agnostic we haven't really spent too much time ffuzzing macOSX in QNX but we've got some again prototypes for it when it comes to system calls in other operating systems they basically follow the same calling convention which is system v AMD64 application binary interface and the object store for POSIX and UNIX operating systems will store file descriptors most of the time as opposed to handles and file descriptors are more or less similar to handles it is basically the most similar thing we can get to handles and for the crash detection we have both the same choices either attach a kernel debugger or rely on the operating system to get some useful information for us in the syslog this is just an example for a single function we're wrapping an IO kit library call it's very much similar to what we do for windows the only difference is that we don't have handles or windows specific helper functions we have IO kit helper functions that will return an IO kit object when it's needed again very much similar when it comes to syscalls on macOSX we're kind of lucky because the XNU system calls are all stored in a single file called syscall.master and this file can even be processed in an automated way to extract all of this system calls with their IDs and their arguments and basically turn this file into a collection of system calls that can later on be consumed by the framework some of the results James already mentioned we're getting some interesting crashes in word.e2k.sys primarily in windows 7 why windows 7? Well probably because most of our users are on windows 7 unfortunately when it comes to other operating systems again we're looking forward to basically spending more time on that the current implementation for macOSX specific and QNX specific modules is just a prototype to be fair. We have some crashes in hypervisors which is something that we never intended to find so this is basically just an annoying thing happening at the moment rather than something we can brag about we also found some interesting bugs in VMware tools and virtual boxcast additions basically these are bones that may potentially be used for escalating privileges because VMware tools is obviously running with an escalated context the sets of that we are using and this is just a set up for the stability runs we haven't even thought about scaling it at the moment mostly because we are satisfied with the results is host operating system hypervisor VMware workstation guest operating system win 764 bits and the VM specs is pretty modest to be fair just 2 gigs of RAM and a single CPU per VM this is just to recap the results from what James mentioned number of VM 16 stability run for 48 hours 65 crashes 13 of them unique and this is before we started blacklisting all of the system causing a lot of problems break down on the type of crashes we have 4 no pointer delays potentially exploitable win 7 fortunately for windows not exploitable on win 8 and win 10 we have some use after freeze 2 of them we have 4 pool buffer overflows basically pool corruptions and we have 3 under the category of miscellaneous basically 3 invalid reduxers violations we haven't properly 3 hours by now this is a breakdown on the crashes of the crashes based on the bug check ID the interesting thing here is to notice that a number of these crashes have been caught only thanks to special pool being enabled for the win32k.cs kernel mod driver so should you run without special pool you end up with at least half of these crashes further work what we can do to improve the framework and to improve the windows specific modules for example obviously we want to increase the coverage how can we increase the coverage the easiest thing and what I think is a very efficient way of increasing the coverage considering the current architecture is object tagging so if you remember in the object store we preserve a bunch of handles but these are handles to any kind of object so object tagging would basically involve adding another field in the BH handles truck and this field will specify the object type for the handle where this handle is pointing to so when we make a request to the object store we will be specifying the type of object that we are expecting to find on the other side of the handle we have well obviously we can implement more of these library calls 500 is a good number but there are so many of them we can implement experimental implementation for user mod callbacks based fuzzing this basically works at the moment but we had some problems with the logging so none of these results that I was talking about are with user mod callbacks enabled in our framework so once we get this working I expect even more crashes another thing is multi threading if you can imagine the lock file that we currently have is a huge lock file of C statements that are plugged into a main function and executed sequentially basically so this is a problem with multi threading all of these runs have been from a single threaded run of the fuzzer obviously we have to work out how to implement proper logging with multi threading at the same time and we can also look at some coverage feedback on CPU features so if you know about NCC's Triforce implementation well would it be possible to get something similar for Windows under miscellaneous we are always looking forward to improving the logging because basically it's just a really tedious and slow process of implementing each one of these library calls with the lock statements for each one of the C statements that we have in the file we haven't looked at handling all of this at all so basically if a hypervisor crush occurs these days we're just going to have to monitor the database and see that the number of crushes is dropping and then we've realized that hypervisor has been down for a few days test case reducer we have considered looking at C reduce this is a program which is basically a test case reducer, language a word test case reducer that can successfully reduce C files we haven't really implemented anything on top of that but the basic idea is that one VM will be reducing the test case will be feeding this test case to another VM, this second VM will be compiling and executing and will providing feedback back to the first VM which is constantly reducing the test case and just in general we definitely need to implement this and logging for the VM and ideally this logging should be hypervisor agnostic so basically this monitoring should be working on VMWire virtual box, keymuse, etc these are the people we want to thank these are all people who provided really valuable feedback and some useful ideas and information when we implemented the fuzzr and basically the core of the framework will be available online I think later next week as soon as we get back to the UK basically and keep an eye on sweet we'll be bragging about releasing the framework I guess if there's any questions I'm happy to take them at the cafe area because I'm being told we are running out of time but yeah, thanks guys