
okay let's say you own an android device and an android phone and of course since you care about security your android phone is locked it's protected either with a password or a pin code or pattern now let's say you somehow misplaced your phone so for example maybe it was stolen from you maybe just lost it or maybe it was even confiscated by law enforcement and now the question is can these people who now have your phone somehow unlock it and access the data that is stored inside and there are a few non-technical approaches they can take to achieve this but we're going to focus on a technical one and since each android device has a usb
port maybe there is a way then they can somehow attack it over usb well normally if you just start plugging in like usual usb devices into an android phone you will unlikely to get any meaningful results to achieve this goal but if you manage to find a vulnerability inside the usb stack that is running inside android then theoretically you could use this vulnerability to overtake the the android device and does unlock it and this was the focus of my talk so hi my name is andrei and i am a security researcher and i mainly work with the linux and android kernels and my talk is called fuzzing usb the rogue with raw gadget and essentially this
talk is about trying to find a particular type of vulnerabilities in the android usb stack so i'm going to start with describing briefly describing the usb attack surface but the part that i'm going gonna focus on are the usb drivers then we're gonna look and i'm gonna explain what fuzzing is and we're gonna we're gonna look into how to apply fuzzing to usb after that we're gonna check out a few ways to emulate usb devices but the way that i'm going to focus on is based on the linux usb gadget subsystem and the the main topic of the talk is i'm going to show you how i used a new kernel module that i developed called
row gadget to do fuzzing usb to fuzz usb drivers within a virtual machine without any external external dependencies so it can be used in any type of a virtual machine and it does not require any additional hardware and finally we're going to look at how to trigger usb box with raspberry pi 0 and i actually have a raspberry pi 0 right here and hopefully we're going to get to the demo where i will show you how to trigger one of the bugs that i managed to find all right all right let's start so first let's check out the architecture of a typical linux usb host i've split this architecture into three parts on the bottom part we have the
hardware layer in the middle we have the kernel layer and on the top we have the user space layer and i'm going to describe this architecture from the bottom to the top so every linux device every linux host device has a usb port and this port is physically connected to a piece of hardware that's called the usb host controller this cost controller knows how to communicate over the usb wire and since each hardware device in linux is supposed to have its own driver the host controller also has a driver in the kernel then this host controller driver is connected to an abstraction layer called usb core and behind this abstraction layer we have the drivers of different
types of usb devices so for example we have the hid driver and hid stands for human interface device and this is the driver for keyboards mice and other types of input devices besides that we have drivers for my storage which is our which are flash drives and we also have drivers for video devices and other like there's there's a lot of them so this abstraction layer the usb core abstraction layer allows a developer to write a usb driver regardless of what controller of what host controller driver is in use and finally on the very top on the user space we have some user space applications and user space daemons so for example when you plug in a
[Music] keyboard and you start pressing the keys these keys are going to be shown in the text editor you're using and this text editor is part is also kind of considered a part of the attack surface and it's running in user space so here the goal our goal is that we control the usb device and we want to somehow attack the linux usb host by controlling the device and we can actually attack each of the layers that we have we can attack the physical ports so for example there is a device that's called usb killer and then we connect it to usb port it's going to charge itself from the usb power lines and then discharge 200 volts
over the data lines and essentially just electrocute the usb port and maybe also the part of the boards maybe the host controller and then there are attacks that can be used like on the very top the user space level for example there was this old windows attack where you plug in a flash drive into a device and there is this autorun file that is on this flash drive and windows will just run it and this way you could execute arbitrary code on windows so since i work with the linux kernel i targeted the kernel layer and the parts i was interested in are the usb core and the usb drivers the reason i didn't really care about the
host controller driver is is because different user different linux devices might have different host controllers and i wanted to find bugs in the lens kernel that would affect every linux device so i wanted to find bugs in the part of the kernels are present on every linux device all right to find this box i wanted to use an approach that's called fuzzing and fuzzing is a way to find box and computer kernels in computer programs and can also it can also be applied to the kernel so i have this definition for fuzzing fuzzing is you is fitting in random inputs into the program until the program crashes and it works like this you generate a random input you execute
the program and feed this input in and then you check did the program crash for example the program could have sec fault it and if the program i mean if the program didn't crash you just generate a new input and you keep going and if some point the program crashed that means great we have found the bug because we generated an input that triggered a crash in a particular program that is a definition of a bug at least one of the definitions so for example if we have an xml parser we would be generating random xml files we would be feeding them into the parser and would be checking for parser crashes and at some point if the parser crashes then
perfectly we actually have found a bug both a bug and a reproducer for this bug in the form of an xml file all right how would we apply this to usb if we look at the definition again so first we replace the word program with the word kernel because we're trying to attack the kernel but then there are two parts of this definition that we need to address so first we need to figure out how do we feed data into usb do we use any special hardware maybe we use some virtual machines maybe we use some other stuff and the second thing is we need to figure out is what kind of inputs does usb accept in general like what data
with do we feed in what's the protocol and i want to start with the second part and talk a little bit about the usb protocol and the most important part about the usb is that it is host driven that means the device when when a device is connected into a host the device cannot just send data by itself it needs to wait until the request from the host so here on the right i have a device and on the left i have a host and let's say we plugged in a device into the host so at this point device cannot start communicating the first communication is happening from the host site and the host has the device like what kind of
device are you and the device for example responds i'm a keyboard and this response is actually done i mean the device sends a few structures to the host and these structures are called usb descriptors these descriptors encode information about the device so for example they decode the class id which is a keyboard and they encode the device manufacturer and so on and there's there's quite a lot of stuff so now again the device cannot just start communicating and now the host asks the host knows how to handle keyboards and now the host asks the device like what kind of keys do you have on what what purpose do they serve and now the device responds i have this
many keys intended for this purpose and the device and now the host says all right you're now connected to which the device will respond okay this is didn't fit into the slide all right so the key part here that the device only responded to requests from the host and this is actually happening so for example if you plugged in the keyboard and you started typing in keys you started pressing on keys the keyboard cannot just tell the host by itself that this key particular key is now pressed the hosts need to ask for it and this is it works like this so the host just keeps asking the keyboard like which keys do you have pressed and it's
asked like any keys first yet the keyboard says no any keys process the keyboard says no and at some point you press the key and the keyboard the keyboard is going to respond now i have this particular key pressed all right so the key part about the protocol is we cannot just send data right so the way a usb fader would work is first it would wait until request from the host then it would generate a response to this request and send the response back and keep doing this in a loop until at some point in time it the father also needs to monitor the host for crashes and if at some point in time the host
crashes that means we managed to find a bug okay this is like a high level higher level overview of how usb fuzzing would work now let's go back to challenge number one so we need to figure out a way how do we fit data into the usb and i started looking for ways of doing that and the first wave that i found is to use the face sensor board and i actually have it right here so this board allows emulating arbitrary usb devices and essentially this board has two usb ports one on the left one on the right and one of them is plugged into a computer that you control and another one is plugged into the computer you're
trying to attack and then on on the computer that you control you can run a python library that allows you to receive usb requests and provide responses to them and this way you can emulate devices and of course since we can emulate devices we can use these this board for fuzzing the problem with this approach is that it requires hardware and fuzzing with hardware is challenging so for example we need to monitor our host we're trying to attack for crashes and if it crashed we need to reboot it and doing this with hardware is is difficult since that it would be great to have some kind of approach that works inside the virtual machine so i kept looking and the next thing i
found is the usb rear gear module in common and qam is a type of a virtual machine and this module allows the host to inject arbitrary usb traffic for the guest kernel that is running inside kiamo and this can also be used for fuzzing and there is actually other it's called virtual usb fuzzer and yeah it uses this qmo usb reader module so the great thing about this approach is that we don't need any hardware we only need camo but this is also a problem because these approach depends on qmo so we cannot use other types of virtual machines to do this kind of fuzzing and this was also a problem for me and the
reason was that i wanted to use a fuzzer called cscollor and i'm going to talk a bit more about it later but the key thing about this caller is it it mainly runs on google cloud engine and google cloud engine is another type of a virtual machine and that google cloud engine does not have the usb reader module so this this approach is great but it was not quite what i was looking for so i kept looking and another thing that i found was the linux usb gadget subsystem and this subsystem essentially allows you to take a linux based board like a raspberry pi zero that i have right here and turn it into a usb device
so there is a way to configure this board so whenever you plug it in over usb it pretends to be a device and the logic of the device is controlled by the software that is running on the board right and most of the linux based work at least most of the popular boards that exist they have the support for this so the beaglebone black also tested and i had an audroid board that also worked and the raspberry pi boards also work and theoretically if we if we have this kind of device we can also use it for fuzzing probably because it allows you to define usb devices and the problem here is that if you're using an
actual linux based board we still require hardware but maybe maybe we can figure out a way to get rid of this hardware requirement so let's try to take a look into the architecture of the gadget site so this this this particular feature of these boards is called this board pretends to be a usb gadget so let's take a look at the gadget architecture and try to figure out a way maybe we can do something about it so on the left i previously shown you the architecture of a usb host and now we're going to look into the architecture of usb gadget and here we're going to start from the upper part so from user space and the
logic of the usb device that is being emulated by linux baseboard is driven by a user space application then there is a gadget driver in the kernel and this gadget driver defines the type of the usb device so for example there is a gadget drivers for emulating keyboards there is a gadget driver for emulating video devices and so on then similar to the host we have an abstraction layer called usb gadget core and behind this abstraction layer we have the device controller driver unlike the host controller driver this driver is for the device controller that knows how to communicate over the usb wire while being a device not being a host right and then we have the usb port
which is supposed to be plugged into usb host and this part on the left allows us to use a linux based board to emulate usb devices so now the question is if we want to use this approach for fuzzing we need to figure out which gadget driver do we use and if you use it just the driver for keyboards there is of course this of course means that we can only connect keyboards which is not very useful when when we're fuzzing we want to connect all kinds of devices so i started looking and i found a driver that's called gadgetfs and it allows emulating almost arbitrary usb devices and the keyword here is almost the way gadget device works is when it
starts it asks the user space applications for the usb descriptors of the device it's going to emulate and then whenever this this gadget stack receives a usb descriptor request from the host the gadget fs is going to respond to this request by itself without asking user space if it receives other types of requests it's going to pass them to user space and ask them for response and then give it back to the host there are two problems with gadgetfs the first problem is that gadgetfs does not pass all usb requests to user space it responds to them on their own um to some of them on their own and that means that if the same usb descriptor is
requested twice we cannot provide different responses and providing different responses would be very useful for fuzzing because this would be likely to trigger bugs in the host and another problem which is actually a bigger problem is that gadgetfest has validity checks for the usb descriptors that we provide to it and that means we cannot send malform descriptors to the host we have to we have to send the correct ones and we want to send malform descriptors because we want to trigger bugs so initially i wanted to remove these countries from gadgetfs i started trying to change the gadgetfs code but it has a lot of legacy code in there also the interface is a bit unusual so
it was hard to adapt gadgetfs instead i just implemented my own gadget driver this took some effort but i managed to do it and this driver it works similarly to gadgetfs but it allows you to emulate arbitrary usb devices and the key differences are that all usb requests that these gadget driver received they are passed to user space to get the response and then there are no sanity checks on usb descriptors i actually mailed this request to upstream so i i mailed the linux kernel patches and they were accepted in version.7 i think this was released it was over a year ago right and i have a github repository in case you want to check it out with some examples
and instructions on how to run raw gadget all right at this point we figured out how to we have our own new gadget driver that allows us to emulate arbitrary usb devices we still have that problem that we need hardware to do that so what we could do here is that this part of the stack the gadget part of the stack is going to be running on our linux based board we can take a separately physical usb host we could plug this board into the host and then run the fuzzer as a user space application and this is a way to use the linux usb gadget subsystem for fuzzing for physical fuzzing of usb hosts
now the problem is that we need hardware right and is there any way we can get rid of the hardware as it turns out there is linux actually provides a solution to this and this solution is called the damage drivers so essentially linux has virtual host and device controllers that are connected to each other within the same kernel so previously we had the gadget part of this stack running on the linux based board and the host part of the stack running on a separate host device but here we can actually run both parts of the stack on the same device or like within the same kernel so this all would be running within the same environment
and this is actually the key slide of my talk so we have our fuzzer running as a eurospace application we use row gadget to emulate arbitrary usb devices we use the damage drivers so that the usb device devices this fuzzer emulates they're going to be connecting to the very same kernel the fuzzer is running on and this way you can do fuzzing inside the virtual machine or inside you can take an android phone and you can just run raw gadget and virtual damage drivers inside and you don't need any external hardware you're going to be fuzzing on an android phone internally and you're going to be reaching usb drivers from from within the kernel right
all right and yeah this this was the approach that i ended up using and i actually integrated this operation to this color syscaller is a kernel fuzzer that is developed by google and it was initially developed to target the linux kernel but right now it targets a bunch of different kernels and it has a dashboard you can check out the dashboard the dashboard shows thousands of bugs that this fuzzer has found and all of them are public you can check out debug you can check the buck report you can check out the zero producers it's essentially dc programs that you can run to trigger a particular bug and i integrated usb fuzzing into syscaller and
so far it has found over 300 bucks in different parts of the linux usb subsystem some of them are in drivers and a few of them are in the usb core layer and the only thing that i failed to do so far is to actually exploit a linux or android device over usb so there are 300 bucks and these bugs affect some of the drivers but not all all of these drivers are present on an actual linux on for example in ubuntu and when it comes to android android also restricts the set of enabled drivers severely so mainly maybe only a few of the bugs they actually affect android but the ones that do affect android i
failed to find a way to exploit them at least so far now i want to get to the final part of the talk which is i think this is the most the most awesome part so first when using his caller to fuzz the kernel whenever c scholar finds a buck it generates a reproducer for this block and a reproducer is essentially a sequence of actions the father can do or like the the the as the fuzzer can do to trigger a particular bug so sis caller has a utility a tool to run these reproducers it's called csx proc so essentially when this caller generates reproducer you can run csx proc and trigger the bug and it works with
usb as well because we're doing the fuzzing in vm we're taking the producer with fuzz we run it in the same event and we can trigger the debug that the father has found but the key thing here is that the interface between eurospace and the kernel is stable and it is stable in the way that we can use any type of a device controller or device controller driver so which means we can take raspberry pi zero so we can take the reproducer that was generated inside the virtual machine we can copy it onto raspberry pi zero and we can plug this raspberry pi zero into the physical host and this way we can replay the
usb communications we generated in a virtual machine with physical hardware right okay actually let me let me try to show you do you still have five minutes this should be enough for the demo so here i have a separate linux laptop all right and i also have raspberry pi zero so what i'm gonna do is i'm gonna plug this raspberry pi zero into the laptop and let it boot
um so what i'm going to do now is it's it's this demo is kind of weird because i need to show you the screens of both my laptop and the laptop i'm trying to attack so i'm going to be using a web camera to record the screen of the laptop i'm trying to attack
okay let's see if this works
okay we can see something all right so this laptop is running essentially it's ubuntu kernel and the kernel version is quite new you see it it's from april 22nd so essentially it's one month old all right so what i'm going to do is on this laptop where i plugged in the raspberry pi zero i'm going to run the d message minus w command it's having trouble to focus the message minus w command which is going to show us the kernel lock in real time right and i'm not actually so for this demo i'm not running the simple the the most basic version of raspberry pi zero i'm running the version with wi-fi and it's called raspberry pi zero w
and i configure this board in a way that when i plug it in it boots and it sets up a wi-fi point so instead of using a bunch of wires to connect to the rdb0 i'm going to be doing a wi-fi connection i'm just gonna ssh onto the board okay now let's see if we get if we have the wi-fi connection so on some technical conferences actually this demo has a problem we do have it because wi-fi is being attacked all the time it's very hard to connect but here it worked all right now we have ssh onto raspberry pi zero so on the left we're going to see the part of the screen that is recording the kernel lock
of the device we're trying to attack and on the right we have the connection onto the raspberry pi zero that is plugged into this device so first we need to insert the raw gadget module and now what we're going to do i have collected the reproducers for the usb bugs that cisco found and i have them right here so this this this is a special syntax that cisco uses to describe reproducers so essentially csusb connect means that this particular line is going to emulate a type of a usb device and the type of the device is described well all of these arguments so what i'm going to do is i have this run script and this route script
essentially runs sees exact proc that i showed here so i'm to do run repro's she's bought and it takes a little bit of time to initialize so essentially what is this is going to do i have about 300 391 to be exact 391 different usb devices that will be replaced one after each other and this raspberry pi 0 is going to be connecting these devices to our physical host and let's hope that this works
okay now it started so as you can see on the right we have the log from the from the part of the code that is emulating usb devices and on the left we can actually see in the message that these the new devices are being connected and if we wait for some time i'm not sure yeah at some point i think this particular this particular sequence of crashes so at this point you can see that the the messages stopped that usually means that we managed to crash the usb stack that is running on the linux laptop and if you could look i don't have the mouse here okay okay now we got something so actually the mouse is broken right now i
mean the touchpad broke because touchpad is connected over usb and will likely kill the usb stack on the machine so you can see a part of the stack trace that is that was triggered and yeah this is just some generic stuff so probably something something something bad happened the problem with running reproducers like this is that some of them corrupt memory and without running a memory crop detector a memory corruption detector on the device it's hard to tell what exactly happened all right we're running very long time so let me let me quickly finish the presentation yeah this was the demo so it worked all right so the summary is that i tried to attack
android and linux devices over usb and i tried to find box in linux kernel drivers so the result of the work is that i used row gadget and i use the dummy virtual controllers to that allow fuzzing either or in a virtual machine and on device and this was integrated in this color and we managed to i managed to find a way to run this reproducers by hardware without any additional hassle and yeah by using raspberry pi zero and raw gadget we get a very cheap tool for usb attacks so essentially phase density costs about 80 bucks this tool costs about raspberry pi zero only is only for ten dollars you can buy and finally the one final not very
important that cisco is hiring so just in case you want to work on linux kernel fuzzing or linux kernel security in general there is a team and at google and they are here in the munich office and they are looking for a new team member so if you want to work on cisco this is the place you can apply so with this thank you and we have no time for questions so just in case you can catch me at the break and ask qualifications [Music]