Owned Over Amateur Radio: Remote Kernel Exploitation in 2011

Video thumbnail (Frame 0) Video thumbnail (Frame 11629) Video thumbnail (Frame 13023) Video thumbnail (Frame 25147) Video thumbnail (Frame 27029) Video thumbnail (Frame 28212) Video thumbnail (Frame 32298) Video thumbnail (Frame 34358) Video thumbnail (Frame 38769) Video thumbnail (Frame 40100) Video thumbnail (Frame 42845) Video thumbnail (Frame 43924) Video thumbnail (Frame 45017) Video thumbnail (Frame 47238) Video thumbnail (Frame 49905) Video thumbnail (Frame 51423) Video thumbnail (Frame 54914) Video thumbnail (Frame 56518) Video thumbnail (Frame 57636) Video thumbnail (Frame 58831) Video thumbnail (Frame 63072)
Video in TIB AV-Portal: Owned Over Amateur Radio: Remote Kernel Exploitation in 2011

Formal Metadata

Title
Owned Over Amateur Radio: Remote Kernel Exploitation in 2011
Title of Series
Author
License
CC Attribution 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal purpose as long as the work is attributed to the author in the manner specified by the author or licensor.
Identifiers
Publisher
Release Date
2013
Language
English

Content Metadata

Subject Area
Abstract
Originally considered to be the stuff of myth, remote kernel exploits allow attackers to bypass all operating system protection mechanisms and gain instant root access to remote systems. While reviewing prior work in remote kernel exploitation, this talk will go over some of the challenges and limitations associated with developing remote kernel exploits. We will discuss in detail the development of an exploit for a remotely triggerable vulnerability in the Linux kernel's implementation of the ROSE amateur radio protocol. In doing so, a number of new kernel exploitation techniques will be demonstrated. In addition, this talk will present a working example of the installation of a remote kernel backdoor. We will conclude with a demonstration of this exploit against a live system and a discussion of future work in kernel exploitation and mitigation. Dan is a security consultant and vulnerability researcher at Virtual Security Research, where he performs application and network penetration testing, conducts code reviews, and identifies vulnerabilities in third-party software. He has reported and corrected dozens of vulnerabilities in popular open source and commercial applications, including more than 50 vulnerabilities in the Linux kernel. He also contributes on the defensive side by submitting kernel patches that implement proactive security features. His current research interests include exploit development, kernel hardening, and mobile security.
Context awareness Group action Range (statistics) Open set Information technology consulting Software bug Local ring Information security Partial derivative Physical system Block (periodic table) Software developer Bit Maxima and minima Control flow Category of being Process (computing) Crash (computing) Phase transition Chain Interrupt <Informatik> Quicksort Point (geometry) Socket-Schnittstelle Computer file Online help Event horizon Crash (computing) Escape character Data structure Contrast (vision) Computing platform Key (cryptography) Information Interface (computing) Code Cartesian coordinate system Exploit (computer security) System call Convolution File Transfer Protocol Graphical user interface Resource allocation Integrated development environment Software Personal digital assistant Function (mathematics) Gastropod shell Backdoor (computing) Convolution Building Code State of matter Multiplication sign Primitive (album) Mereology Web 2.0 Data compression Semiconductor memory File system Cuboid Process (computing) Information Resource allocation Vulnerability (computing) Area Connected space Proof theory Remote procedure call Data structure Asynchronous Transfer Mode Game controller Existence Server (computing) Functional (mathematics) Implementation Service (economics) Observational study Link (knot theory) Virtual machine Exploit (computer security) Web browser Twitter 2 (number) Operator (mathematics) Gastropod shell Integrated development environment Software testing Interrupt <Informatik> Game theory Backdoor (computing) Context awareness Memory management Kernel (computing) Pointer (computer programming) Event horizon Rootkit Communications protocol Operating system Buffer overflow Local ring
Vulnerability (computing) Firewall (computing) Memory management Exploit (computer security) Array data structure Component-based software engineering Core dump Social class Physical system Window Buffer overflow Vulnerability (computing) Physical system Social class
Context awareness Group action Software bug Array data structure Mechanism design Sign (mathematics) Virtual reality Exception handling Physical system Constraint (mathematics) Mapping Building Netzwerkschicht Digitizing Web page Electronic mailing list Sound effect Process (computing) Green's function Buffer solution Interrupt <Informatik> Quicksort Point (geometry) Web page Proxy server Open source Constraint (mathematics) Firewall (computing) Latent heat Ring (mathematics) Computer hardware Computer worm Communications protocol Implementation Address space Buffer overflow Code Field (computer science) Line (geometry) Cartesian coordinate system Exploit (computer security) System call Frame problem Convolution Sign (mathematics) Loop (music) Software Video game Backdoor (computing) Window Convolution State observer Building Length Code Stack (abstract data type) Semantics (computer science) Subset Component-based software engineering Flag Extension (kinesiology) Vulnerability (computing) Data recovery Open source Physicalism Open set Connected space Software testing Right angle Code Remote procedure call Information security Implementation Server (computing) Service (economics) Real number Virtual machine Exploit (computer security) Field (computer science) Twitter OSI model Natural number Gastropod shell Spacetime Software testing Backdoor (computing) Wireless LAN Context awareness Addition Serial port Twin prime Memory management Bound state Planning Denial-of-service attack Stack (abstract data type) Pointer (computer programming) Communications protocol Buffer overflow Computer worm Address space
Convolution Frame problem Email Functional (mathematics) Installation art Length Mereology Total S.A. Field (computer science) Software bug Latent heat Software testing Address space Module (mathematics) Email Data recovery Debugger Length Code Total S.A. Frame problem Convolution Connected space Type theory Pointer (computer programming) Function (mathematics) Compiler Backdoor (computing) Buffer overflow Row (database) Renewal theory
Convolution Randomization System call Run time (program lifecycle phase) Distribution (mathematics) Structural load Code Parameter (computer programming) Stack (abstract data type) Neuroinformatik Pointer (computer programming) Semiconductor memory Randomization Logical constant Data recovery Bit Control flow Buffer solution Code Quicksort Web page Point (geometry) Functional (mathematics) Game controller Numbering scheme 2 (number) Revision control Chain Crash (computing) Read-only memory Term (mathematics) Computer programming Boundary value problem Directed set Booting Hydraulic jump Address space Distribution (mathematics) Stack (abstract data type) Binary file Exploit (computer security) Convolution Uniform resource locator Pointer (computer programming) Kernel (computing) Software Function (mathematics) Backdoor (computing) Routing Buffer overflow Computer worm Address space
Point (geometry) Convolution Functional (mathematics) Installation art Code Constraint (mathematics) Mereology Area Pointer (computer programming) Read-only memory Natural number Semiconductor memory Gastropod shell Computer worm Spacetime Constraint (mathematics) Inheritance (object-oriented programming) Data recovery Memory management Stack (abstract data type) Convolution Entire function Frame problem Pointer (computer programming) Software Network socket Backdoor (computing) Routing Buffer overflow Spacetime Asynchronous Transfer Mode Computer worm Row (database)
Convolution Standard deviation Functional (mathematics) Game controller Installation art Length Code Data storage device Stack (abstract data type) Mereology Metadata Telephone number mapping Revision control Writing Pointer (computer programming) Hooking Read-only memory Semiconductor memory Arrow of time Data structure Communications protocol Address space Default (computer science) Constraint (mathematics) Data recovery Weight Data storage device Code Computer network Bit Convolution Uniform resource locator ICMP Pointer (computer programming) Function (mathematics) Read-only memory Phase transition Quicksort Communications protocol Data structure Asynchronous Transfer Mode Spacetime Computer worm Address space
Module (mathematics) Convolution Run time (program lifecycle phase) Multiplication sign Code Bit Stack (abstract data type) Deadlock Exploit (computer security) Convolution Wave Wechselseitiger Ausschluss Component-based software engineering Quicksort Communications protocol Communications protocol
Convolution Scheduling (computing) Context awareness Thread (computing) Multiplication sign Strut Sheaf (mathematics) Counting Disk read-and-write head Stack (abstract data type) Electronic signature Encapsulation (object-oriented programming) Semiconductor memory Befehlsprozessor Pattern language Information Software bug Structural load Electronic mailing list Bit Complete metric space Thread (computing) Electronic signature Process (computing) Pattern language Modul <Datentyp> Quicksort Data structure Reading (process) Functional (mathematics) Numbering scheme Module (mathematics) Metadata 2 (number) Boundary value problem Data structure World Wide Web Consortium Buffer overflow Module (mathematics) Information Inheritance (object-oriented programming) Uniqueness quantification Counting Public domain Stack (abstract data type) Frame problem Convolution Pointer (computer programming) Sheaf (mathematics) Boundary value problem Scheduling (computing) Buffer overflow Flag
Point (geometry) Convolution Game controller Memory management Stack (abstract data type) Control flow Limit (category theory) Exploit (computer security) Pointer (computer programming) Hooking Computer programming Phase transition Hydraulic jump Backdoor (computing) Buffer overflow Row (database) Spacetime
Email Convolution Asynchronous Transfer Mode Group action Context awareness Installation art Code Spyware Stack (abstract data type) Type theory Hooking Strategy game Phase transition Gastropod shell Computer worm Process (computing) Context awareness Email Data storage device Code Mereology Control flow Convolution Hooking Kernel (computing) Process (computing) Phase transition Strategy game Interrupt <Informatik> Quicksort Backdoor (computing) Physical system Asynchronous Transfer Mode Computer worm
Context awareness Group action Functional (mathematics) System call Run time (program lifecycle phase) Code Interior (topology) Hooking Semiconductor memory Pattern language Computer worm Process (computing) Address space Physical system Context awareness Run time (program lifecycle phase) Interior (topology) Control flow System call Convolution Subject indexing Process (computing) Pointer (computer programming) Function (mathematics) Interrupt <Informatik> Pattern language Quicksort Table (information) Physical system Address space
Convolution Empennage System call Equaliser (mathematics) Strut Virtual machine Spyware Metadata Revision control Wave Carry (arithmetic) Hooking Read-only memory Phase transition Rootkit Gastropod shell Computer worm Process (computing) Data structure Stochastic process Code Stack (abstract data type) System call Thread (computing) Hooking Process (computing) Kernel (computing) Pointer (computer programming) Rootkit Formal verification Heuristic Quicksort Backdoor (computing) Physical system Task (computing) Computer worm
Convolution Group action System call Thread (computing) Code State of matter Parameter (computer programming) Stack (abstract data type) Mereology Pointer (computer programming) Semiconductor memory Abstraction Exception handling Physical system Interior (topology) Staff (military) Thread (computing) Process (computing) Befehlsprozessor Ring (mathematics) Interface (computing) Interrupt <Informatik> Normal (geometry) Quicksort Physical system Data structure Resultant Asynchronous Transfer Mode Asynchronous Transfer Mode Numbering scheme Service (economics) Rule of inference Read-only memory Rootkit Energy level Computer worm Interrupt <Informatik> Data structure Installation art Interface (computing) Code Stack (abstract data type) Line (geometry) Cartesian coordinate system System call Convolution Inclusion map Pointer (computer programming) Kernel (computing) Rootkit Function (mathematics) Exception handling Computer worm
Convolution Addition Code Closed set Stack (abstract data type) Line (geometry) Control flow Stack (abstract data type) System call Convolution Pointer (computer programming) Crash (computing) Process (computing) Pointer (computer programming) Rootkit Gastropod shell Computer worm Process (computing) Quicksort Hydraulic jump Physical system Address space Hydraulic jump Address space
Inheritance (object-oriented programming) Spyware Inheritance (object-oriented programming) Real number Mereology Shareware Shareware Process (computing) Rootkit Gastropod shell Process (computing) Gastropod shell Quicksort Computer worm
Axiom of choice Point (geometry) Server (computing) Computer file Code Virtual machine Set (mathematics) Client (computing) Stack (abstract data type) Mereology IP address 2 (number) Utility software Gastropod shell God Scripting language Directory service System call Connected space Shareware Type theory Rootkit Password Quicksort Communications protocol
NP-hard Convolution Thread (computing) Entropiecodierung Length Multiplication sign Software bug Hooking Semiconductor memory Series (mathematics) Fuzzy logic Extension (kinesiology) Partial derivative Physical system Randomization Web page Entropiecodierung Infinity Physicalism Bit Electronic signature Befehlsprozessor System programming Interrupt <Informatik> Quicksort Data structure Booting Web page Point (geometry) Functional (mathematics) Numbering scheme Link (knot theory) Variety (linguistics) Real number Patch (Unix) Virtual machine Maxima and minima Coprocessor Portable communications device Revision control Goodness of fit Crash (computing) Read-only memory Internetworking Operator (mathematics) Computer programming Computer hardware Data structure Communications protocol Booting Address space Hydraulic jump Fingerprint Distribution (mathematics) Information Run time (program lifecycle phase) Code Computer network Limit (category theory) Exploit (computer security) Convolution Frame problem Uniform resource locator Loop (music) Kernel (computing) Pointer (computer programming) Function (mathematics) Read-only memory Family Communications protocol Window
thanks everybody for coming despite the late hour this is owned / amateur radio and we're going to be talking about remote colonel exploitation first a little bit about me my name is Dan I am a security consultant vs are in Boston mostly doing at the network pen testing code review that sort of thing I've published a few bugs mostly I focus lately on the Linux kernel and especially on linux kernel exploitation of mitigation so what are we going to talk about today first I was going to provide some motivation on you know why I wanted to give this talk and what I hope you guys will get out of it and next we'll just dive right into some of the technical details of what are some of the challenges associated with developing fully working remote colonel exploits next we'll take a look at what some of the past work has been in remote colonel exploitation and try to draw some trends there and look at areas that that haven't been covered as much and then we'll get into the body of the talk which is sort of a case study of an exploit that I wrote for a remote stack overflow in the linux kernel's implementation of the rose amateur radio protocol and this part of the talk will be in sort of two phases in the first phase I'll sort of explain exploitation of the vulnerability and the second phase I'll explain the details of the colonel backdoor that I installed during the exploitation phase and then finally we will wrap up taking a look at some future work I think remote Colonel exploits are to speak for themselves as to why they're useful it's sort of this keys to the kingdom concept where you have instant remote root access to a machine that you previously had no interaction with but especially when you compare them with the challenges that are facing you when you're trying to exploit client-side systems like browsers for example you know if you have a browser exploit your frequently facing exploit mitigation technologies like a SLR and X or dep and sometimes that those require the existence of a second vulnerability to to bypass and at that point you may be running inside browser sandbox for example as ie9 and and chrome and most recently Safari not provide so if you can leverage a third vulnerability to escape that sandbox you may need to escalate privileges using a fourth vulnerability because you're running is an unprivileged user and that seems like a lot of a lot of pain so I prefer to skip all that what I hope you guys will get out of this talk this is not actually an amateur radio talk despite the really misleading title we're going to talk about enough of amateur radio to understand the vulnerability that I'm using but really this is sort of a vehicle for me to talk about exploit development methodology so hopefully if you guys don't have any experience writing exploits you'll hopefully get a sense of what are some of the building blocks that we can use to exploit these kinds of vulnerabilities what are some of the steps that we need to go through and i'll also be showing off a bunch of sort of exploitation techniques which i think is far more interesting and useful than doing a study of an individual bug because bugs come and go they get fixed all the time but exploit techniques and learning how to mitigate them are really define lots of you know lots of bugs and sort of the whole point of this is to take a look at this exploit and identify what the weak links in the chain are what are the parts of the exploit that aren't really done so well so that we can identify what are the easiest ways to protect against these kinds of exploits so despite their advantages remote colonel exploits are not trivial to write and i sort of identified three key points as to why why there are some extra challenges associated with these kinds of exploits the first of these is that the environment that you're working in is incredibly fragile if you're dealing with a remote user land exploit for example like a web server or an ftp server or something like that frequently if you fail if you're dealing with some sort of memory corruption vulnerability and you miscalculate some offsets or your exploit works fails for some other reason frequently you'll crash the application or service in some cases it needs to be restarted manually and others it'll be restarted automatically if you're dealing with a service that actually forks child processes for each connection you may not even crash the service itself you'll just crash the child process and you essentially have very minimal consequences for failure and can continue to try to exploit it in contrast if you fail at a remote colonel exploit in nearly every case the Colonel's going to panic and the box will fall over and not only will you have lost your chance to exploit that machine you've lost any chance of doing so with any sense of stealth it's a little bit noisy to crash an entire machine the second the second main obstacle in my opinion for these kinds of exploits is that you have very little control over the environment that you're trying to exploit then this is sort of a shared property of all remote exploits if you're dealing with a local kernel exploit where you have an unprivileged account in the machine you have a lot of sort of exploit primitives sort of building blocks that you can use to make writing exploits easier for example you it's very easy to trigger the allocation of data structures on the kernel heat you know you can open files or sockets or create shared memory segments and all of these resources have structures on the kernel heap and you can sort of trigger these allocations in such a way as to massage the heap into a state that's conducive to exploitation likewise you can trigger the calling of function pointers in the kernel by performing operations on these structures that you've allocated and finally there's this huge silver platter of information the colonel gives you if you're a local user through interfaces like on Linux the proc file system that will really help you find out where things are in kernel memory and help target your attacks if you're dealing with a remote Colonel exploit you don't actually have any of those capabilities right away but we may see how how you can sort of build them up from other exploitation primitives you might have and the final challenge in my opinion with writing these exploits is they frequently occur in what's known as interrupt context so you know 10 second operating system 101 when a process makes a system call it is executing kernel code in what's known as process context where the threat of execution has a user land application a process associated with it but in contrast when you're dealing with receive it like asynchronous events like receiving networking data the colonel is running in what's known as interrupt context it doesn't have a process associated with that threat of execution and this is a very sort of delicate and difficult context to exploit because the end goal here is usually to execute code in user land because you know a shell is a really nice convenient way to interact with the system and that's sort of what everybody wants the challenge is how do we get from this sort of hostile interrupt context environment to executing code in userland and the answer is we need to find a way to transition from interrupt context to kernel mode process context in which we're still running kernel code but we now have a process associated with us and then finally from there to actually executing code in user land so before I get into what I did I thought it would be prudent to talk about what's been done before so I studied base I looked up and researched every remote Colonel exploit I could find anywhere and identified 18 exploits that have been talked about or published for 16 unique vulnerabilities he's written by 19 people nine of them have full public source code many of the metasploit modules three of them have sort of partial or proof Rukh Khan's proof of concept source code and the rest were sort of discussed in detail at conferences without code and these these exploits cover a wide range of platforms solaris and OSX have not had any weaponized remote colonel exploits that's sort of future work if you're into that sort of thing breaking these
down by what operating systems they affect half of the 16 vulnerabilities were in windows only four of those were actually in the windows core components three of them were in various wireless drivers and one was in a semantic firewall you know three and netware which I don't think anyone still uses netware three in various BS DS and two in Linux one of which was in a third-party driver and breaking these
down by vulnerability class as to what vulnerability was exploited a full three quarters of these 12 of the 16 were typical stack overflows and I think this is probably because these vulnerabilities are incredibly conducive to exploitation that they're very well understood the steps of exploiting them are known three of these vulnerabilities were heap overflow switch our frequently much more difficult and then one of these windows SMB issue is actually an array indexing issue I'm not sure
there's actually enough data to draw meaningful conclusions about trends here but 2007 was a busy year for Colonel exploitation
so just a brief walkthrough of some of what are in my opinion the highlights of past work on remote colonel exploits Barnaby Jack did the first work that I'm aware of he started in 2004-2005 and he exploited a remote stack overflow in a semantic firewall application and he demonstrated a lot of really cool things especially detailed shell code examples for how to transition from running in the kernel to actually executing userland code and he also demonstrated a kernel backdoor that in many ways was sort of an inspiration for the one I ended up in implementing next in 2006 seen on RN from immunity they announced they had green apple which was a remote colonel exploit for Windows and that's sort of the first commercially available remote colonel exploit that I'm aware of also in 2006 HD more Matt Miller and Johnny Cash published three remote colonel exploits that were allowed to metasploit in various Wi-Fi drivers 2007 there was an open BSD ipv6 vulnerability which was really awesome that was the first public remote Colonel heap overflow that I'm aware of they did some nice work on that and they also bypassed userland NX protection as a non executable stack heap etc final highlights immunity has a canvas exploit for MS 08 2001 which is a Windows igmp v3 vulnerability and that was a really difficult to exploit windows kernel pool overflow that people were questioning whether it was exploitable before they announced they had a reliable exploit and then finally in 2009's crack you published a an exploit for a Linux kernel vulnerability in the sctp protocol which is a remote Linux heap overflow and I think one of the great contributions from this exploit is he introduced a really neat trick that leverages a 10 a 64-bit specific page mapping to easily transition from interrupt context to executing code directly in userland just sort of drawing some trends from from all this you know work I did reading up on what's been done before you know three-quarters of these issues were stack proposed but none of these actually had to contend with having non-executable stacks in the kernel itself because the feature it has wasn't introduced at that point so my exploit will will try to address that next none of the issues neither of the two issues on Linux actually were stack overflows in interrupt context which is sort of a particularly difficult context to exploit things in because you need to do a bunch of cleanup s crack you and twist published an article in frack 64 called notes on Colonel exploitation or something that effect and they sort of describe the steps you need to go through to do this but it was for a vulnerability introduced for the sake of demonstration and I wanted to provide a real life example and the last observation is that six of the six of the 18 exploits were four issues in a tour to 11 code so i think wireless drivers could probably use some some improvement and now i've gotten to the good stuff before we start talking about how to write this exploit or what the bug is the target system that I'm going after i'm using a 32-bit x86 physical address extension kernel and the pae component is significant because it means the colonel now has an x support as in the kernel stacks and Colonel heap Colonel data are all now non-executable so we can't just execute code on the kernel stack immediately without doing something first they also you know these Kernels have user land and X protection as well so if we're going to somehow introduce code into a user process we also need to do so in a way that honors page permissions we can't execute code on a user land stack without without modifying its permissions and then finally because we're on a 32-bit machine we can't leverage S crack use trick that was specific to AMD 64 to make that transition from interrupt context to userland we're actually doing testing I just had to vm zai chose a boon to temp 104 the attacker is just a desktop machine the victim is a boon to server because that's a pae build for debugging I just use kg TB and for the actual networking I was not sitting in my apartment doing like with radio equipment driving my girlfriend crazy I i was using vpq which is an implementation of x.25 amateur radio over ethernet so my VMS can talk to each other without me needing to buy radio hardware or get a license and just because of the nature of the exploit it's written entirely in x86 assembly except for the code that sort of ties it all together and sends it over the wire so this is the advisory that Debian put out for the vulnerability that I'm going to be exploiting dan Rosenberg first day they spelled my name wrong they they spelled it right in actually five other issues in the same advisory got it wrong in this one which is some sort of sign reported two issues in the Linux implementation of the amateur radio x.25 PLP protocol a remote user can cause a denial of service by providing specially crafted facilities fields this is a pretty interesting denial of service so just a brief overview of the protocol we're going to be exploiting just enough detail to talk about so you understand the vulnerability that I'll be taking advantage of roses a fairly rarely used amateur radio protocol and it's a network layer that sits on top of x.25 which is sort of a more commonly used packet radio protocol so in addition to seven by takes 25 addresses Rose rose nodes have 10 digit numeric addresses to identify them and they sit supports only static routing and it does so using a digit Peter mechanism where a host can essentially say all right i'll accept packets from this x.25 call sign and forward them along to this one so when to when two hosts issue a connection to each other using rose they exchange what are known as facilities and this is sort of just a list of supported features for that connection and one of these facilities fact national digi's allows one host to give the other host a list of digitas just so it can figure out its routing stuff and in the linux kernel implementation i noticed that when they went to parse this particular field in the Rose frame they read this length value directly from the frame and copied all this digit peter data without any bounds checking into a statically size buffer on the kernel stack and this is the sad code you can see at the top line there just reading that length value right out of the frame data using it as an upper bound for this loop that then copies do data in in x.25 a dress size of chunks which are seven bites into either the destination or source array and those arrays are living on the stack you may also notice that there is a constraint here the seventh bite of every x.25 address is actually ANDed with a flag that indicates whether it's a source or destination digit Peter and that means in our payload we need to obey that constraint every seventh bite needs to be consistently greater or less than 0 x 80 otherwise you know 117 bite chunk might be copied into one array and then the next one might be copying into a different array and it would be very difficult to handle and it would be a pain so this sort of just required me to go through the exploit and manually just check that this constraint was satisfied now we've got a plan of attack we've got a vulnerability and we want to actually you know exploit it and the first step is to actually gain control the instruction pointer so we can control what the Colonel's going to do and from that point we need to actually start executing code next I decided that my exploit would install a remotely triggered well Colonel back door because that sounded like fun and finally we will have to do some cleanup to make everything keep running so first
triggering the bug was actually really the easy part I took 10 minutes after I found it you just what I did was essentially cannibalize the the rows kernel module that already existed so that it whenever I made a connection to someone it would send out my evil Rose frame instead of a normal one and this evil Rose frame just had this particular facility field that was vulnerable followed by a two big length value and then a bunch of no op instructions just for the sake of testing to see if I can actually trigger it this is what the
frame looks like you have your header total facilities length which didn't actually matter a null byte fact national is the specific type of facility fashional digi's is the vulnerable facility itself and then this length value which we're setting 20 x FF which is 255 which will is more than enough to cause the overflow and then a bunch of 90s and so you recompile or rows module and then you make a connection to your vulnerable hosts and it causes a stack overflow on the soft irq stack which is an interrupt handler that's receiving this data you can see on in the debugger you know our hosts have we have overwritten the saved return address on the stack and then when that vulnerable function returned it returns to all 90s which is the the value that we put there so now we control the instruction pointer as most people who
have written serious exploits know getting control of the instruction pointer and actually executing code can be separated by a lot of work traditionally if it were like 1995 we would just sort of return into shellcode that was stored in our buffer that was copied onto a stack and then we'd be running code and that's all you need to do the first problem is we don't actually know where the soft irq stack lives in memory because its allocated at runtime and it's going to be different on each boot that's pretty easily solvable you just sort of return to this trampoline function that will do like a jump ESP and jump into the stack wherever it is the second problem though is that since we're running a pae colonel the soft irq stack on which because their overflow is non-executable memory so if we try to return there the kernel just crash and this means we need
to employ a returner eight in programming so the basic idea of return oriented programming is because we've caused our stack overflow we now control the return address where this function is going to go after it returned is finished doing whatever it's doing and we control a bunch of data on the stack past that safe return address and we also notice that every return instruction will direct execution to the address that's on the stack and then increment the stack pointer to the next place so using this we can actually just chained together little pieces of code at known locations in the kernel to do essentially arbitrary computation I say at known locations because this actually does rely on the fact that you know where stuff is in memory and this is a fairly reasonable assumption in the kernel world if you're running a distribution Colonel like Ubuntu or debian fedora they're shipping binary kernels which means everyone with the latest version of ubuntu has the same has the same kernel image in memory in terms of the code so it's fairly reasonable to assume that if you know something about your target then you essentially know we're and memories certain instructions live and there's no sort of randomization of the colonel at all to make this a little bit better you can actually choose these gadgets these little pieces of code that you're executing in such a way that they're more likely to appear across multiple colonel builds so now actually looking at some code what our route payload actually what we wanted to do is to actually make the stack that we overflowed executable so that we can run code on it and the colonel has a really nice convenient function that'll take care of all the hard work for us called set memory X and set memory X just takes two arguments the first one is an address that you want to mark executable and the second one is the number of pages from that point that you want to mark so we're in the colonel so the calling convention two functions actually has the first three arguments of the functions in registers so we just need to keep that in mind so what the ROPS tub does is first we actually want to load the stack pointer which points into the stack that we want to mark executable into the eax register because that's the first argument register to this function will actually align it to a page boundary because that memory expo will cry a little bit if you don't have things page aligned then I just chose arbitrarily let's mark four pages from that point into our second argument register which is EDX return into set memory X which is just going to mark the soft irq stack executable and from that point we can just return into a jump ESP instruction instruction at which point execution will jump into the software Cusack and start running our code so at
this point we are running shell code on the software Cusack in kernel mode great but we've got a problem the amount of data that we could have copied into our overflowed region is limited to 255 bytes just by nature of the particular particular bug that we're exploiting and we've already used a whole bunch of that to get up to this the safe return instruction we've used more for our route payload so we're running very low on space and Colonel payloads can be quite big so we really need to overcome that space constraint but it's useful to
keep in mind that that's just the part of the packet that copied into the overflow region we have this Rose frame that we sent that can be thousands of bytes big living somewhere on the colonel heap and I found experimentally that one of the parent functions to the function that we cause an overflow and actually has a pointer to this to this Rose frame the entire rows packet that we sent over so what we can do is now that we're executing code all we need to do is walk up the stack say is this a colonel pointer yes no just heuristic alee and if it is you can follow it and look around in memory and we'll put a tag in our rows frame so that we can find it and then you know we'll eventually just find our Rose frame on the colonel heap will mark it executable just by calling set memory X and then jump into it so now we've
overcome our space constraint we can execute arbitrary length payloads running in kernel mode right now and the goal here is I want to install a kernel back door in the ICMP handler because that is so just some some data
structures to sort of explain what I had to do here it's not very complicated there's this sort of global array at a known location you know because it's it's in kernel data called the inet protos array and this just is an array of pointers to these net protocol structures there's one for sort of each IP protocol which is redundant like IP proteaceae p1 there's UDP ICMP and the first member of this net protocol structure is a handler function pointer that just that's what gets called when the colonel receives data for that protocol so if we can overwrite that function pointer for the ICMP protocol then whenever we receive ICMP data it will call in to our code and we can we can move on from there so hooking ICMP is pretty straightforward I decided to use the soft irq stack itself as a place to sort of put stuff just for the exploit because we've already marked it executable so it's a good place to put code that we're going to need later it's it's persistent it's not going to go away while the Colonel's running and it's a very safe place because on linux kernel stacks are 8 kilobytes big by default but the bottom four kilobytes is guaranteed to ever be written into otherwise the optional 4 kilobyte stack version would never work so anything in the bottom four kilobytes of the soft irq stack outside of the metadata at the very bottom of it is a great place to store stuff so what we do is we copy our hook and we'll explain what that does in the second part when I describe the back door but for now it's just some code that we want to run into the soft irq stacked just for safekeeping and then we want to actually install a hook so that execution will be redirected to it first we notice that the handler that I want to overwrite is in read-only memory which is sort of a pain x86 has a nice little way out for this control register 0 has a bit called the right protect bit and if you flip this bit then you can essentially right into read-only memory with no problem which comes in handy so what we do is we flip this bit now we can write in to read only memory we write the address of this hook that we just copied in into the ICMP handler function pointer and then it looks something like this wow those are really narrow arrows I guess so whenever some whenever our kernel receives at cmp data it will call that handler function pointer and that will execution will go to this hook that we installed it will run whatever code we choose to run there and then presumably when we're done we're going to call the original ICMP functions so that ping still works and stuff like that finally the last phase
of this exploitation component is to actually make sure that the colonel keeps running because all this work is sort of for nothing if if you do it and then the colonel just collapses so the biggest problem here is that we've wiped out a pretty big portion of the stack by causing this overflow and if we don't do any cleanup then the colonel is just going to crash the first bit of cleanup
I needed to do has to do with with some locks so at the time of the exploit the Rose protocol was holding to spin locks just for mutual exclusion purposes and if we just sort of carry it on as if nothing happened then the road stack would actually deadlock and then the colonel wouldn't would lock up the album here is these spin locks live inside the rose kernel module which is loaded at runtime so we don't actually know where it is fortunately it's
actually pretty easy to find it there's this global modules variable which is the head of a linked list of loaded kernel modules so what we can do is we just follow this linked list until we find that module named Rose and read this sort of module structure that is hanging off this linked list until we find where the data section of the Rose module is now that we know where the data section is module is we can sort of scan it for this bite pattern that represents a distinctive signature of what these spin locks will look like in memory and that's unique so that that will always work and then once we find them we can release them by I think it's incrementing them the second bit of cleanup I needed to do has to do with the preemption count so on Linux every process has this variable called preempt count which sort of encapsulates a bunch of information related to scheduling and if the colonel calls an interrupt handler as it did when our malicious Rose frame was received and returns from that interrupt handler and the preemption count isn't what it expects it to be in the past the schedule would panic and everything would fall over more recently they put in a check where if it's not what it expects it to be it actually just complains a little bit and fixes it for you which is really nice for exploitation and save me a lot of trouble when I was first getting this up and running but for the sake of completeness what will avoid that warning because we don't want anything to be logged it's really easy to find the preemption count it just lives at this in this thread info structure which is at the base of whatever process it is Colonel stack so all we need to do is we know where the soft irq stack is we just find the base of it and then this variable is that a known offset from that base and we just decrement it appropriately and that's all we need to do now finally we need to do this
actually clean up so the colonel will keep running so recalling that you know stacks are sort of divided into frames which represent you know function contexts essentially our overflow has wiped out some number of frames including all the metadata that's needed to keep things running so what we need to do is we actually walk up the kernel stack until we match the signature that I prepare ahead of time that represents this is a good this is a frame boundary this is a good place for us to put the stack pointer and everything will keep running as normal once we return from there um it sort of as if we magically teleported up a few up to a few pair of parent functions so let's go over what we've
done so far and that that's the end of the exploitation phase at that point if you send your exploit over you know it installs a hook and the colonel keeps running and not it would never notice anything happening so what we've done so far we trigger our overflow gain control the instruction pointer and then we leverage return oriented programming to mark the soft RQ stack where the overflow took place executable and then jump into a shellcode stub on the soft irq stack next because we have this space limitation we find the entire rows frame on the colonel heap mark it executable and jump into it next we install our Colonel back door by hooking the ICMP handler and then we do some cleanup that we need to do to keep the colonel running next we're gonna talk
about the back door so now at this point
whatever an ICMP packet is received our hook that we put in kernel memory is going to run now we want to talk about what that hooks going to actually do so the first thing it does is it checks for this sort of arbitrary magic tag that I just made up in the ICMP hen header and I decided that I wanted to have two distinct kinds of packets to handle I wanted to have an install packet and what I want that to do is sort of caused it to keep shellcode that I put in the ICMP packet around for later just sort of let it sit in kernel memory somewhere and then I wanted to have a trigger packet that causes that shell code to execute somehow and this is user land shell code that I want to be dealing with and these packets should be able to be sent independently so you can sort of install a payload and come back a week later and cause it to trigger repeatedly so we need to develop a strategy for how we're going to actually make this happen the problem here is the ICMP handler we've hooked is also running an interrupt context and we want to get to user land we want to execute code in userland so the first phase we need to actually transition from interrupt context to kernel mode process context where we're still running kernel code but it now has a process associated with our execution in the second phase we want to actually hijack that process that's now associated with our execution and cause it to execute our user land payload so for the first phase we
checked the magic tag when we receive an ICMP packet and if it's an install packet then we'll just copy the payload that's in the packet into a safe place and we're going to keep using the soft our cue stack as a good place to store stuff if we get a trigger packet then we
need to make that transition to process context and in my opinion the easiest way to do so is to hook a system call because whenever a process calls the system call it will then be executing kernel code in process context which is where we want to be how to do this is
has it's been done before I find the system called table at runtime by issuing an SI GT instruction which is an x86 instruction that finds the base address of the interrupt descriptor table and I just index into this table and pull out the handler for int 80 which is system call so that's sort of the entry code for what happens when you call system call when you make a system call I scan this function for a bite pattern indicating it's making a call in to another table and this other table is the system call table so you do that now I know where the system call table is and the system call table is just sort of like a table of essentially function function pointers that represent handlers for what happens when you make a system call I close or open or etc the system call table on Linux is read-only but we've already figured out how to get around that we just flipped that magic bit in in cr0 we can write to read only memory so what we do is we just keep that system call handler whatever one we want to hook for later because we're going to need it and we'll write the address of our hook code into the system call table so now whenever someone calls that system call it will execute our code
because we want the ICMP stack to keep working then we just actually called the original ICMP handler that we kept around so the machine still things so
now we want to move on to phase two so what we've done is we've copied our user land payload that we want to execute eventually into kernel memory and some process comes along and it's going to call the system call that we chose to hook and what we need to do now is hijacked that process to execute our user will encode first of all we're only
really interested in processes that are running with root privileges it would sort of suck if we went through all this trouble and got to connect back shell as a nobody user so the challenge is how do we actually check that this random process that we hijacked is a root own process and you could do this by actually following various pointers in metadata associated with that process but each of these structures sort of is unstable they change a lot between different kernel versions you'd have to do it heuristic alee and it's sort of a pain be really nice if we could just
call get you ID because that's something we know and understand it's a very simple interface that will immediately tell us what our user ID is but the question is is it possible to call system calls from kernel mode I mean logically it doesn't really seem to make sense because the system call is designed to be an interface that user applications can call to request services from the colonel so what happens when when you make a system call via into a tea from kernel mode I'm just curious how many of you if you had to guess would think that you could do this without a problem it's pretty good how many of you think that some issues may arise if you try to make it into a tea from kernel mode how many of you have no clue what I'm talking about thanks for being honest it turns out that most system calls will work perfectly fine when you call them from the colonel and and the details of this you just need to know some x86 trivia but basically the problem that I thought might arise it has to do with the fact that when you transition from user land to kernel mode you switch stacks to a kernel mode stack and I thought that that might screw things up but this tax which only happens when you're changing privilege levels so if you make a system call from normal mode you just skip the staff switch and use whatever stack is still there and this is just just like any other interrupt that is intro privilege level as in there are lots of interrupts that can be called from from ring 0 and there's really no problems here there are a few exceptions to this rule some system calls actually require the stack to be in a certain state using this per thread register structure and when you do it from kernel mode these assumptions aren't really are violated so it won't work properly and these are things like fork exactly clone but those are really things we don't really have much of an interest in in calling from kernel mode anyway so now back to the actual challenge we wanted to see if our processes owned by root all we need to do is load the eax register with the sis call number four get you ID and call and 80 it's really easy then you can just check the return code if it's 0 then we know our processes owned by root and we'll carry on if it's not 0 then we'll just send that process along and have it call the original sis call handler that we hooked so it just does whatever it was intending to do and keeps going next
we need to actually inject our userland payload into this process that we've now hijacked so the kernel stack as a result of that stacks which that I just mentioned actually has a pointer to the saved userland stack pointer so you know when when the process enters kernel mode the the CPU pushes the user land stack pointer on to the kernel stack so it can when it returns from that system call it knows to put its stack back to where it was so we just let's put our payload on the user line stack because we can just read that pointer know where it is so what we do is we copy that user line payload that we installed earlier as part of that sort of install packet from kernel memory wherever we put it onto this processes userland stack because we have a modern system the user line stack is non-executable memory so we can't immediately execute code there but that's easy enough to fix we'll just call em protect by loading the appropriate system call number and a TX and arguments and make it into a tea from from kernel mode to mark the user line stack executable
now finally sort of one of the last things we need to do is actually make sure that when this process that we're hijacking returns from the system call that it's in it runs our code so in addition to saving the user line stack pointer the colonel saves the user land instruction pointer on the kernel stack so that when it returns from the system call knows where to go so we just need to overwrite this this pointer on the stack with the address of this user line shell code that we just injected and then when it returns it'll run our code in userland because we want to do things
perfectly and make sure nothing crashes we actually after we've done this well jump to the original handler for that system call that we hijacked so if we hooked closed for example we want the close to still actually happen now the
sort of part where you get to use your imagination because we set this up this way you can use whatever user lend payload you want connect back shell is good you can use metasploit payloads for all I care one thing that I did do is that regardless of what userland payload you provide I prefix it with a stub that makes sure that the process you hijacked keeps keeps running and this all this stuff does is Forks a new process and then the child runs the shellcode that you injected wow it's rowdy over there the child runs the shellcode that you injected and the parent process of the fork will jump to where it was originally going to go so that you know if you're if you're hijacking something important it will keep doing whatever it was doing and be none the wiser so now is the real fun part where I get to demo this and pray to the demo gods so I've
got two VMs up and running this is awful
the password is password like all my machines so we're going to set up the
Rose server stack this is just a little shell script to create the appropriate interfaces and and find them likewise on the client just bring up the Rose protocol stack I have aliased call to just make a rose call from this host elite one to the victim host loser one using the Rose port associated with this host so when I type that um we've loaded our Colonel exploit into this attacker machines colonel so whenever we make call it'll send our exploit over to the victim so we'll do that and it's done you don't have to clap yet because I haven't really proven anything but you'll notice that absolutely nothing was logged that's all just residual from bringing up the Rose stack and you would have no idea that this happened to you but that machine is now totally owned so we will demonstrate the back door that I just installed as a part of running that exploit so I'm going to bring up a server that I wrote this is actually an egg's 25 connect back shell which was sort of a pain to write so this is just a server listening for x.25 connections and this is my little magic ping command that just builds your your special ICMP packet I'm going to install this x.25 shell code that I compiled I'm going to trigger it by hooking syscall six which is closed it's just a good choice because it gets called frequently and the IP address of the victim so we will send that in the pack it over and wait a few seconds and pray to the demo gods and we have a root shell now of course once you've once you've compromised a host you need to always check for the zero data txt file living living in the home directory because you've earned it well that's really difficult to read well the point is I also audited the userland utilities associated with this network stack and the x.25 Damon actually has a missing return code check on set you ID so if you're actually handing out on privilege shells using X 25 which I'm sure all of you do it you can actually make a connection essentially fork bomb the Machine and then make another connection and it will fail the set uid call and it will give you a root shell instead of an unprivileged shell that's sort of a funny pug alright this exploit has a lot
of things that could use improvement first off the thing that really bothers me is that I hard-coded a bunch of things there are some advantages to using hard coding and this is sort of a toss-up between reliability and portability you know if you're hard coding something you're you're reasonably sure that it's going to work every time on the machine that you targeted it for versus like a heuristic approach where you're doing signatures or something that will work on a wider variety of hosts but may fail some of the time even on host that you've tested on a physical address extension colonel like the one I targeted it's it seems mostly unavoidable that you have to use wrap so the goal is here really just minimize the number of Rob gadgets that you use and minimize the amount of hard-coding of other data structures that you have to do if you're running an on PA Colonel The Situation's much better you can actually just get by with a single known instruction like a jump ESP instruction for example because you can jump right into the stack because it's executable and it may be possible to do something with with partial overwrites like overriding a portion of the frame pointer a stack pointer or doing some sort of spray approach where you don't even need to know any instructions so the fact that it's pae makes exploitation significantly more difficult the next sort of limitation in my opinion is using this magic little ripe protect that is is fun and easy technically speaking it's not the safest thing in the world it's a per CPU bit so if you have a multiprocessor system there's actually a small risk of flipping this bit so you can write to read-only memory and then what if that thread gets scheduled out and scheduled back in on the other processor before you make the right then it would try to write to read-only memory and crash I have never seen or heard of that ever happening that's a very very small race window but it's possible and it might be worth considering alternative ways to write to read-only memory they might be possible to just leverage Colonel data kernel functions that already exists that will sort of do this in a safe way and then the challenge becomes finding those at runtime now sort of more general future work on the offensive side because these exploits really rely on knowing something about your your target I think remotely being able to fingerprint a colonel you know identifying is this a distribution what distribution is it what version is it likely to be is really essential in sort of gaining the information you need about your target to be able to build your exploit I'd also like to look at other other fun packet families for exploitation ear to Bluetooth x.25 are all less tested and probably have plenty of fun bugs and of course finding that that IP bug that breaks the entire Internet is always future work on the defense side I think it's pretty clear that the weakest length of the weakest link of this exploit is that you need to know things about the kernel you need to know those those known instruction locations so if we rent do something like randomizing the kernel base at boot which is a sort of Linux kernel patch series that I have tinkered with and sort of started to try to get up streamed that really totally prevents all this coteries and your exploit no longer works in the absence of some sort of way of remotely disclosing kernel memory which is possible but I've actually never heard of such a bug additionally it's pretty clear that that the more exotic networking protocols are not tested as rigorously and could probably use some work and next it would be really nice if if certain functions like set memory X were in line so that you can't average them in return oriented programming so it's not quite so easy to mark things executable and finally a sort of long-term work it'd be really good if there were sort of policies implemented in the kernel that prevented changing permission changing page permissions after initialization and I think the PAX team is actually working on something like this so now we've got two questions you guys have any questions y'all just stunned yes sorry what was that yeah the bug was found through inspection i actually had no real radio amateur radio experience prior to that i am not a licensed operator so i thought was found through auditing if I hooked get you ID in my exploit that would probably cause an infinite loop yeah because yeah because yeah exactly you would um your hook would get called and then you would call get you idea in your hook and it would call your hook again don't use that one I guess good point I'm sorry would you mind speaking up I you mean if I understand did you did you mean creating a USB device that sort of exploits itself you need to get one on the system Oh to send them I if you were doing with real radio hardware how will we talk afterwards any other questions I saw one over there can you just disable interrupts oh um that would probably help ya for further write protect that you mean yeah I think that would probably work yeah good idea John no no I don't want to marry you John alright cool thanks guys
Feedback