← All talks

BSidesAugusta 2018 - Prashant Anantharaman and Rebecca ".bx" Shapiro - Ghost Busters ...

BSides Augusta · 201834:2474 viewsPublished 2018-11Watch on YouTube ↗
Speakers
Tags
CategoryTechnical
StyleTalk
About this talk
Prashant Anantharaman (@parsingpunisher) & Rebecca “.bx” Shapiro (@bxsays) In this talk, we describe ELF-based access control (ELFbac) and how it can naturally mitigate Spectre (variant 1). ELFbac is a novel technique for defining and enforcing policy at an intra-process granularity. Its mechanisms allow us to isolate semantically distinct code and data by placing them in separate ELF sections. This isolation can be used to effectively “hide” sensitive data from code that handles untrusted inputs. ELFbac leverages the ABI format and the forgotten capabilities of the ELF loader as first-order security primitives.
Show transcript [en]

all right so we are here to talk about elf the ABI and computational privilege where wait okay um so why don't you introduce yourself I'm prashanta and I'm a PhD student at Dartmouth I work with Sergey brothers and I work on language theoretic security and and I'm Beck's I am a senior security researcher at narf industries and I studied with Sergey Broadus in the trust lab previously I recently graduated and my specialties are elf boot loaders I've been working on dynamic analysis I try to do defense research and yeah why are we here we kind of want to tell a story about a project at our lab has been working on for a while called elf pack which we

think has this nice way of defining and enforcing the intent of a programmer and we found that it has a really nice nicely works with Spector and acts as a nice mitigation and it's sort of 10 gentle to all the other mitigations that are there for spectre variant 1 and Prashant will talk about that later but with the elf back we we see that the ABI the application binary interface really merge it really well is a good boundary and a good mechanism to capture programmer attends before we get into this though I want to start with a story one day in the live freezer die States I made my way through you know 10 feet of

snow uphill both ways to the Dartmouth trust lab I wanted to go for a visit and when I got there I got the traditional trust lab greeting backs we're surprised to see you here they're so nice to me and so if I respond and I might have been there for free food I forget it was you know about January after the specter and meltdown was publicly released so they tell me you know lately we've been thinking about Spectre yeah so has everyone this is January of the month in which all these details were released yeah okay and maybe Sergei kind of goes off on a tangent with Russia well we're thinking elf back may naturally mitigate Spectre

v1 and we'll kind of go through and talk about what elf back is and what Spectre vert variant one is but this is sort of the conversation that was going on and I'm like huh like this doesn't make sense to me hmm let's think about this a little so you know several months later we're kind of trying to get this working and well it seems to work yeah I was wrong to doubt but we also ran some more experiments to just think to look at timing try to get an understanding of these micro architecture micro architectural arcing artifacts that were measuring that are part of Spectre and so we did so how did we get here now well long long ago

well 2013 in the galaxy far far away well the Milky Way people wrote really bad software and I guess they still do and so in the far user reaches of northern Appalachia we thought of elf back and this is sort of a lab project and basically the idea was that's elf files which are the executable library binary file format of Linux and a lot of similar systems they retain a lot of interest semantically interesting metadata that are subsequently ignored by the runtime and so yeah that makes sense and some of us didn't know what else was but we decided to look at it the lab and well go on Sergei software but if design is

split into parts the libraries compilation units functions object files kind of match this and in other words these parts are semantically related to code and data so you'll see the libraries will be the crypto library well you'll see libraries for two particular functions but also you'll write files a part of program this implements a linked list this implements database search and so forth and information about these different parts are expressed in L files they're stored in separate and distinct elf sections at some during some points of the compilation process and eventually brought together and these these metadata are for compilers static linkers and the binary tool chain and not wastefully disregarded during runtime but if we use them the intent

can be there can be a policy that enforces intent at runtime even if the software is compromised because we can start actually reflecting this intense of what should be accessing what through what we ended up doing was page table of permissions and we decided to do it in sort of a runtime state-dependent so if we know the software is running and trying to work with crypto well then it can access the keys but if it's processing user input it shouldn't be and we can reflect this on this ABI level using page table permissions as the software executes now imagine a world where sections of an elf are types and linking it's a policy that works

across these types the runtime loader constructs an address space based on these elf metadata and I have a little like mock-up and each different colors a different section some of them are libraries some of them are than being executable but it's you know the read is executable the yellow is read only and the green is read right and maybe we're we're looking at like the web server or maybe they're it has like a limp and G in there well volar ability in a library in the overall executable can and propagate and make the entire executable vulnerable and when sections are policy objects the policy can be explicitly put in to prevent you know say Lib PNG from

leaking any key material and this is what we call elf back at ABI based intra sort of memory access control list and we'll discuss the implementation later but I've been saying ABI a lot and just like so we're all on the same page this is you know an example ABI that for and also X a 64-bit x86 and you see it actually defines how different components of binary objects such as libraries and executables interact with each other and these standards and and also I mean it also does it also talks about how variable length arguments are taken in functions and different data types but it really defines a lot of what elf files are based out of and we think this is a nice

granularity to work on perhaps just right I mean it's really hard to compare elf back against say memory protections and selinux it's like comparing apples to oranges I mean they're both sweet but there's definitely tangental things that are hard to compare but if we're looking at how memory protections are done generally with kernels it's read/write/execute different parts of memory and it's sort of fixed during the runtime more or less it can be changed that sort of an explicit decision without back permissions can be dependent on these sections that we define at compilation time that a developer can say this contains key material this contains you know buffers for an image that we're processing and this is the code that that processes

keep serial and these are the code that processes untrusted inputs and during the execution phase we can start having like known entry points into these different phases I am processing input I am processing key material vanessi Linux has this very small granularity of falls individual files and neat labels and it can be kind of hard to work and what forgets to do who is you know our leader of our lab is show that the ABI sort of the sweet spot between between different kind of layers and what we think about in policy so the security role offends the tractability and also just like how much effort it takes to build this policy and remember if it looks like a

duck quacks like a duck but needs batteries you probably have the wrong abstraction and so maybe just having like memory read/write/execute is not enough and maybe some of will you should really rethink the way we enforce policy with in executing process you know fak I mean it's more it doesn't protect against all attacks it's not there to be your buffer overflow however up to to prevent buffer overflows however if there is fun pained in a certain phase and not necessarily be propagated in two phases of execution where it's processing and key material and what it's nice about it is it can capture and enforce developers intent on these layers of boundaries of libraries and so

forth and may application so the moral of the story is that a library's and sections of memory can be trusted equally yet that's what the current state of things are and when an executable is loaded all the libraries are in the same address space and everything is treated the same in terms of policy elf pack allows us to express enforce these inter process access controls the ABI granularity so processes or processes don't have to treat their entire address space as equal so to try to make this a little more real you can think of a case study of some software that fetches and you compresses image PNG files you know over SSL so that you can think of the

different phases of execution it goes through and you also think about the regions of memory that accesses during time during this flow during each phase of execution so actually the SSL will be initialized and then another in that you'll read its keys and then it'll perform some SSL again and it'll probably read the keys again at that point and suddenly it's invoking Lib PNG to you know to process this image for some reason then that's only working with an input buffer and then there might be some more application logic that is working on the output of Lib PNG and each data code segment that we pointed out here the SSL initialization look in G the keys and so forth can be

put in there are little sections in the o file without too much trouble it's sort of part of what elf does is add little markers to different sections inside the file that tell the loader what is code what is data but we will add a little more information so if we're using both open SSL and PNG what a make this / the loading pian Lippe and G into address space and you don't really know how this loading and how the PNG will affect like if there is an a weird effect with Lib PNG we need to understand that and we especially in the current model where everything is sort of treated equally in the address space

and you need to kind of understand how this affects our mental model so if this PNG file a million current model overwriting some critical data and from that you might end up you might end up having the execution do something different or leak properties and so with the separate separating permissions for each section suddenly the keys are not readable by by own Lim PNG and Lib SSO will only access it its own code its own data and you'll explicitly can put these explicitly define places where that you can intersect well I think I might skip this but this is just reinforcing the state machine that that got through when we're loading and OH cell and processing

different sections that are at play but yes if there is a bug at one suddenly the memory map can kind of get a little messy with attacker control data I'm going to start this going in some background now about elf since this is called elf back what else does naturally is it defines the divides text and data and metadata for loading into different sections and so there's two views of the file the static compilation view which understands each section separately and the runtime view were it actually doesn't it forgets about these separate sections and just knows that this group of data are actually it's executable these are read-only these are read rights and the elf is what demarcates

these sections and there is sort of a purpose - well this is executable you know that there are some some code in there and what lies behind these elf sections really is kind of interesting I mean tenant we tend to lose this information where you might have three separate C files that we compile into object files in the end they kind of get they are still separated but they're in with we can actually with the right tools keep those separate just as different pieces of policy but still have them all be loaded and actually listening a piece of code or a piece of data into a different section is fairly simple and there's some you said that

attributes section and then you give a section name and this is in C and that will tell the compiler to put it in its own section and so that for our purposes you can apply policy - and now Prashant will take over yep so we heard from Beck's about what elf is and a little bit about the background so now let's let's look at how a stack is how we can actually write a policy for Spectre and what Spectre variant one was so inspector variant one basically a malicious actor can influence the control flow of the program so if you look at the code section code example over there like there is an untrusted offset which is being accepted from the

input or from its being accepted from an input and there is an if condition and that particular check has to happen the decode inside the section is obviously supposed to execute only when the condition is satisfied but what happens is that when so some processors not some process almost all processors do this speculative execution over here where it predicts that there is a chance of that particular offset being lesser than the limit and it actually runs the code that is inside it and hence it puts the data that is inside the section puts the data that is being read into the cache so what happens over here is that the victim function can it loads the

secrets from the privileged memory and that particular memory gets gets loaded into the cache so why is it really challenging to mitigate this particular specter variant one so if you look at this this is the proposal on LLVM in the client compiler so their technique over here was to so if you see over here there is a condition and then within the condition they use a ternary if condition again so their whole thing was that if the speculative execution branch is happening then you force the condition to be checked again so what why would you run it again it makes no sense and gr SEC decided to run their own thing where they are using static

analysis to figure out where this speculative execution happens and then mitigate them by using L fences and that is what even Microsoft does with qrq specter where they figure out using static analysis where this particular speculative execution bound stick bypass can occur and then they introduce an elephants instruction over there or - like mitigate this particular variant so how about Linux first Linna store world's he looked at the bunch of patches and he was like it's not that it's a nasty hack it's much it's much worse than that and then yours like Intel is not serious about this and Intel doesn't really want to patch this but then how did they eventually go about it this was the

first patch so it was again an e SML fence and it was the exact same thing as what Microsoft wanted to do and then they came up with another patch which was supposed to fix the previous one where again they were like array index no spec which is like saying that this particular array there cannot be any speculative execution on this one it is again a hack as you can see like you really need some other technique to figure out where you need to initialize your arrays this way it's not a holistic patch you still need some sort of static analysis or some other technique to figure out where this has to be added so yes people are

approaching it with a line-by-line process or by static analysis and there are some other techniques that you need to use to like figure out where the problematic locations are and that's where if that comes in like we are giving the power back to the programmer or the developer and we are helping them enforce their intent with respect to the data and the code sections in the program okay so let us apply as back to the variant one proof of concept so if you look at the data in the program the data that gets leaked it is like this particular secret string it's all way so in the proof-of-concept they have a secret string and we are mainly

interested in that one string that gets leaked in the cache and so we put it in a separate section using the attribute method in the eff API so we put it in a separate section and this is the syntax that we use and we also like put the different methods in the program in separate sections so as I said like you to specify you want to separate like the code and the data in separate sections so we have two methods in our code and we put them in separate sections and then like so this is the state machine that we were using so of course like in the original proof of concept this is the this is the sequence of operations

that happen but they weren't really and forcing into the state machine so we have two different states the init and the go so in the unit state the secret has to be so the secret is a global so of course like in the beginning of your program it has to so your program when the program initializes it has to be able to read and write to this memory location or else your program will seg fault right over there so like in the beginning of your instead in the beginning of your program you want to give readwrite access to this particular global and then as soon as the initialization happens you don't want your program to like be able to access

this particular memory location so as you can see in our policy like we have readwrite access to the secret in the beginning then we revoke it and we only have like executable access to the particular function that actually executes right after it so this is how this is our tool which is called methyl so mythril helps us like programmatically represent this particular state machine this is written in the this is written as a ruby DSL or domain-specific language and what it does is that it converts this particular state machine that is represented over here into code and it it puts that in a separate section in your S binary in this section called the dot elf back

section and this section gets loaded by the kernel when the program is loaded so how does it back really mitigate specter variant 1 so since sensitive data and code is like put in separate sections and the periods of execution that are less trusted like not given access to the sensitive data and like parsing and modules of code that access libraries they are only given access to data that it really needs to access so we can write a policy that only writes to what we trust and only writes only the libraries that we trust can actually write and all this is actually enforced by the hardware so why does this work so the page table permissions are set by the elf back

policy and the processor respects these page table permissions that are set by elf back and the speculative execution branch like fails to load the secret and the TLB and the caches are flushed during state transition so whenever there's a state transition we flush the TLB and the caches because we don't want the data from the previous state to be accessible in the next one and of course there is no timing leakage and the side channel is also mitigated because of the permissions that are side ok so conclusions a bi-level memory objects are the sweet spot as Bex described earlier the benefit of using as back is not just a specter mitigation as we were describing earlier it's more of a

holistic solution where it mitigates a wide range of interprocess memory attacks and the Polish policy can be modified if you're adding additional libraries to a program later on or if you want to ice if you want to isolate these libraries or if you want to address new foreign bugs there is a performance hit of course because like we are we are doing TLB flushes and we are also forcing straight transitions and page faults so of course there is there is a performance hit and we are working on improving that and the the policy the policy crafting tool that we described metal it needs some improvement and we are like trying to build a test framework to query and test

policies that are crafted so yeah I guess we can take questions now oh we didn't ask questions we have stuff to give away so I just thought of one what type of cat are these No okay that's $2 someone oh yeah sorry um well they're Russian or Mongolian maybe it has a similar name or maybe it has it's a different name that I know perhaps but we'll give it to you module is how I know them the leader of our lab or former leader calls them the privacy cats because they hate being tracked and they can't be investigated they have a really poor immune system so they if they're in domestic the in captivity they kind of die from sickness

we have three more things to give away unless someone wants to ask a question and we can give you something for asking a question yes yes

that is interesting I think you would want a little user input to say these are like the crown jewel data that we don't want leaked and then you can probably have some static analysis that generates a policy that works with that we have some played with some generic policies that enforce loader actions so there's a lot of processing that happens when the runtime loader brings a binary into memory and a lot of interesting tricks can be done with the metadata elf to get it to do random things such as well I built a compiler that compiles a turing-complete language into elf metadata and it's because it it can happen or like this turing completeness happens and arises because the metadata

don't respect their intent and so we wrote a policy that will work on well generated like well intended generated elf files during loading but would prevent the the turing-complete weird machine that rises out of these metadata so that's be like a basic policy you can add to everything for loading but for general like the idea is it's up to the developers or to people who know the software to be like these are special and these are special phases or untrusted phases and then put together something with that so you have like a coarse grain basic policy that helps at some level oh you get a prize other questions no other questions it's hard to really have the the to really

compare the performance hit because it's really dependent on the number of state changes that we have so I think that was some default like the loading policy is what they measured and timed it for across all binaries and Mbutu it was really because of the state changes yeah so like if you have a program that I don't lead that does like an SSH an SEC handshake in the beginning and then does something that's completely trusted then like the first key read only happens in the beginning once so in that case you will not see that much of a performance hit but if it's something where like it keeps switching to an untrusted state really often like it keeps accepting

user input or network traffic so where you need to like pass the network traffic again and again and you want to put the parsing in like a separate state in that case it becomes a bit more complicated and there will be some there will be there may not be 5x performance edge but there will be a performance area yeah there are hardware their hardware tricks that we're not using that people who actually know how to work this kind of thing and care do know and would tell us to use so we can do better but we don't at the moment do you want another prize we need another question then or we can ask one oh great

there's some examples so elf Beck org has some pointers to a couple repositories one is the x86 implementation the another is an arm implementation and one day will barge the two but they have examples like ping pong where it you know enforces ping pong and one that uses the enforces something with Lib C the prevents Lipsy from accessing anything and then main executable so the easiest example in the repository is ping pong where you just have two different methods ping and pong and one variable and you want to like restrict access to that particular variable from ping but tom has access to it and so on so like that is the easiest example there is but there are more complicated

ones as she said like Lib C and so on yeah I mean and we need some better tools to get like Lib C is a little finicky because it depends on the build of Lib C sometimes it has some interests it does so like this is a problem with our tools to have like better support for these weird tricks that Lipsy does and loader does but that's you know future work for this particular project ly we use the x86 version of elf back yeah oh we didn't get we don't the right hardware to test the arm very spectra v1 proof-of-concept because we're poor academics or at least I was now I work in industry any other questions

if you don't ask one I'll ask one okay umm the state motto or saying for New Hampshire it was alluded to earlier oh you were the first okay oh yeah you already have you in the purple sure I think you for a second yes free or die cool that was our last so if anyone else thinks have a question we can still answer feel free to trade prizes all right well thanks for coming I'm sure you want to like get ready for the after party thank you