New Ethereum talks, every Monday. The week's conference uploads by event, in your inbox.

Loading player…

From bytecode to bugs - Sifis Lagouvardos | Dedaub

ETH Belgrade CommunitySat, Oct 7, 2023, 12:00 AM

From bytecode to bugs: how security analysis and decompilation help us find vulnerabilities in smart contracts - Sifis Lagouvardos | Dedaub

Transcript

yes thank you hello I'm civil level vardos I'm a residence and this talk I'll give some information and insights about our tooling static analysis mainly but others as well that we've been using on the ethereum and found on blockchains to find real life vulnerabilities so I work at ddub which is a security company that's been on the space for a few years now the company's Founders nevergreen against monologues have an academic background with many years of experience static analysis and many others on the team as well have been working on Academia I personally have been working on ethereum tooling for four years and most of this work has been on the honor the compiler Pipeline and Analysis pipeline which have some said bits okay so our research technology as I said is in static analysis and what we do in static analysis is we try to create a model of all possible program behaviors which of course is not always possible but let's say that that's the goal and one design and static analysis we need to keep a very clear balance on three things the first one is scalability which is very important because you want to be able to analyze as many programs as possible the second one is completeness so you want to be able to model as many program behaviors as you can in order to cut as many bugs as possible and the third one is precision so you want to have very precise results in order not to burden the people that have to go through the reports that your program analyzes make with useless stuff which in turn makes them not want to use your tools so for in our work we use declarative program analysis meaning that our programs are defined as a logical as thousands of logical rules which allows us to in many cases express some tough problems in a small and readable Manner and make use of a modern runtimes to to speed up our analysis process okay a lot of the work I'll present here today is deployed on our contract focused blockchain Explorer contract Library which is available at that link and I will also have a demo here today the basis of conduct Library like when it was built it was to expose our the compiler to to the world and after that we've added a lot a lot more features that are common to other blockchain explorers but also others that are not found elsewhere so the first thing I want to focus here today is the compilation and in our case we use the idea Force framework is an open source framework that we've been developing for uh many years now and like it's a vital part of our whole pipeline so I'll try to not make this talk uh too technical but it will have some technical information so we'll start with a simple example and this example is a like it has a single storage very solid the smart contract first of all it has a single storage variable a Constructor which says that owner variable to the message center and a guarded external method that allows the owner to withdraw funds now what we analyze we don't analyze the source we analyze the the runtime evm byte code and this byte code doesn't have the Constructor information in there so this is only the Constructor is only used when the Contracting is initialized and in our simple example it will have two external methods the one will be the getter for the owner field and the other the guard method that is defined now when we compile it and we get the random by code we get something like this which can be very easily disassembled to something like that and so this is evm bytecode in the assembly form and we can see a few things first of all there are no first of all it's a stack based virtual machine meaning that in order to understand what variables or values these statements operator you need to model the stack instructions which is not usually it's not easy at all for humans and it's not easy for static analysis as well so what we need to do is create is take this bytecode and elevate it to a high level of abstraction and a few other things I'd like to mention is that the contract has a single entry point meaning that there are no concepts of public or private functions and all of these are implemented using uh low-level instructions a sequence of instructions and we have heuristics to detect all that and another important point is that first of all something you need to know is that this orange statement that identifiers are the the beginnings of what we call the basic blocks and the basic blocks are sequences of statements that will always be executed one after another and how many you can see that on the basic blocks we've highlighted on the right is that in many cases the second basic block you can see that you push a statement identifier and then you jump to it so looking at this basic blocking isolation you can see where the next one is but if you go below below that it's a basic block where you cannot see if you look at the Naturalization uh what the next one will be and this is very important because this is where static analysis comes in these blocks are used all over the place they are set and we use static analysis to create a model a model of all the possible behaviors in order to be able to decompile that and when we do the compile it we get something like that which as you can see is more high level so we have the edges between the blocks like the control flow is recovered and what we also have is we've resolved these operations to the variables that they use or constants which allows us to better understand the program however so this is a code for the owner getter so this code just fetches the storage variable but as you can see it still has lots of low level information that is required for like compilers to to put onto support high level features in a very low level virtual machine like solidity so what we do after that is we have libraries that run on top of this and produce high-level facts and in this case the facts will look like that so we removed lots of the sifting and masking operations and we see that for example variable 125 loads storage variable that takes part of storage slot zero and then we return that which was previously done through a series of like memory stores and memory loads and this is the level at which our analysis operator so we have the compilation we have a normalized form which is useful for analysis but we also have many libraries that help us get a lot of high level inferences so we don't need to care too much about the low level three customer of course we do care about them and we have to model them at every stage and using that form we can also get a search like the compilation output and as you can see in this case it looks very close to what's uh to watch in the original Source like of course it's a very simple program and in the bottom right what you can see is also the function dispatch code which is not present in the original Source but we keep it for completeness so it's it's how the program decides which function is actually being called so of course the biggest use of this pipeline are security analysis and most of our analysis are built on top of our symbolic value flow flow engine analysis engine so the symbolic engine and you can think of it as a technique that combines the good things about static analysis the fact that it's faster the fact that it covers many uh program behaviors tries to cover most of them and the Precision enhancements that symbolic execution will give you and in this focus on a specific subset of clients which we found to be very useful and they can be generalized as or in the form of a sensitive operation that can be read by an ambivalent scholar so this allows us to express things like a sense of operation could be anything like in erc20 transfer from many sensitive goals to D5 protocols so it's a very expandable framework and Let's find let's say an example of such a vulnerability so this is a pattern that used to be common in yield aggregators like a few years ago basically that have a harvest or rebalanced function that was callable by anyone and it allowed them to withdraw or reward the contract like the specific strategy had accumulated on another D5 protocol swap them to the base token let's say and deposit them again to that other Define protocol to continue getting ill from them so this is a very similar pattern and they thought it would be all right to just let anyone call it however there's an issue with that and that issue is specifically because they do not specify what the the minimum amount they need to get out of this swap is which basically allows any other contract or mov both to uh to tilt the pool essentially first influence it on their benefit by add by adding a lot of by swapping lots of a tokens to that pool leaving this the swap of this contract to get very little benefit from the swap it does in this function and then swapping the original tokens I got back to to get like what this would have got an essentially stealing it's a profit now this is a complex case and something that's interesting and brings me to one exponent is that static analysis for that will give you this contract if you like you have a specific line for it but it will not tell you when like when the conditions of uh this to be vulnerable are met so this is where we need our alcohol infrastructure so we start from static analysis and we move on to something that contains a lot of information about the blockchain's state and past transactions so this information about the blockchain state can be needs to be processed basically so it it could it can be information about the token balances and allowances between contracts in EOS let's say it could be proxy related data so this proxy this proxy yes this proxy uses that implementation and that part implements that particular contract uh proxy protocol let's say and also we need information about the contract storage and we've also found that information on past transactions can be useful because let's say in the proxy case you want to see that a proxy hasn't been initialized so how we do that one way to do it is to take through past transactions okay so this uh brings me to our next uh our second product other than contract Library which is Watchdog it's it includes all the features of contract Library but it's a security oriented so it allows people to Define their own protocols or upload like in development call to do it our static analysis round off of that and security results and other doors can inspect them and it allows you to combine or our researchers to combine the results of a static analysis and their inspection so we can find out what's really vulnerable statically by looking at the code and combine that with static information to find real life vulnerabilities in the wild and it also has a lot of freedom regarding transaction [Music] information basically it allows it we developed an SQL like query language to allow people to create their own triggers for transactions to set interesting events like to say if this function is called under this condition by this function of my protocol is called under some condition triggered and send me an notification and over the past two and a half years we've used this system to perform a number of high profile vulnerability disclosures in total there are 10 disclosures some of which let's say are swaps like the one I showed you others could be defined on various things like [Music] elitably transfer forms or delegate calls or [Music] vulnerabilities regarding certain proxy patterns and also other like we've recently had some very high profile ones not all of them were aided by Static analysis but most of them were and as you can see yeah this vulnerabilities were in major protocols and they got a lot of high level and a lot of rewards for finding them and Reporting them uh some other uses of gigahertz that I wanted to to mention are impacted so we've been approached by the ethereum foundation a few times to assess the impact of certain uh certain proposed changes to the AVM semantics to all or as many as we can like but mostly all deployed Concepts and see on the ethereum mainnet basically we get the pattern we they say that this could break some smaller or bigger things and we use static analysis to identify contracts that have patterns that could potentially be affected by that by this change and then we also use Dynamic information to to verify that and to assess the impact that way as well perhaps the most interestingly certainly the most relevant one was the recent study we did about the removal of self-destruct which like two weeks ago was presented to the core developers meeting and helped them uh hasn't take the decision to accept aip6780 to the next hard fork and change the semantics of self-destruct essentially only allowing to work if the contract is created and deleted in the same transaction so another interesting use I wanted to to mention is that we recently used a gigahorse to identify a solid the compiler bug this compiler bug was fixed in version 0.8.19 and the the description of the bug is the following basically as I mentioned in the beginning of the talk contract that selectable through in the contracts Constructor doesn't belong to the random bike because it's useless there so if something if the bug was at if Library functions especially were called only during only on the Constructor they would still end up being part of the byte hole and for this for some proxy patterns this was catastrophic essentially for example for Diamond proxies it would cause a like that over 90 percent of the deployed code to be that code and the interesting thing that we detected this when trying to actually debug our tool because we noticed that we we have cases where a very high number of dead blocks is reported so I thought something is up like this isn't correct and we went in and found that it's actually bug in the compiler okay so thank you for your time now we'll do a quick demo of contract library but feel free to check out the gigahorse framework as well it's available on GitHub and so this is the front page of conduct library with is used as a conduct based blockchain Explorer and let's say you have some bytecode you want to decompile so you click on the bottom on the top right you paste that byte code in hexadecimal form and you click the compile now this has had already been decompiled otherwise it would enter a queue and finish in a couple of minutes so as you can see we entered that and we recovered what looks like a unit shop to pull and as you can see like our UI also indicates that this is deployed on the mainnet so here you can see that the compiled code and other levels of abstraction with output we output something like looks like Yule which can allow for reuse of that code the three address code I showed you earlier so we can use that to go to the uni shop V3 pool and find its deployment now again here we have the compiled code that was the same as the previous one you can go to its source as well so it has the contract sources through that we we have a music way to communicate with the contracts the storage read it and also the mappings and other parts of that and we also have a lot of information about the token related things like erc20 balances on that the balances of the contract so as you can see this has USD and West so it's a USD West pool we also have the allowers for the contract so with with contracts or EOS have given this many allowance to this conduct allowance to transfer their money and they are quite a few as it's a unisa pool we also have information about past transactions and you can click on on them and get a an overview of the transaction and tell him token transfers balances and also the transaction Trace and we can also go back and like quickly show some other ways to to call that to interface with its uh storage to read or write transactions but yeah if that's not easy right now it's okay I'm happy to take any questions certain questions yes please oh oh hi uh I think is a great tool for real experience engineering and so I have two questions about that the first one is 02 is a past sensitive right so how to avoid the past explosion I mean if there are too many code reviews like some basic blocks so how do you avoid past past sensitive since your tool is past sensitive right I'm sorry I don't get the question uh for example if there are some basic blocks which are reused multiple times yeah so there might be too many passes in the control photograph right yeah so uh what we used to to help us with that we use a program analysis technique that's called conduct sensitivity so it's an abstraction where like our kind of the conditions that we use basically tells you that every time you analyze a basic block you try to remember certain things from its uh past the past callers because we couldn't like let's say remember all the past callers so we have abstractions and heuristics that help us remembering this and they allow us to differentiate the different uses of the same basic block in different contexts and we also have some other like small hacks to get around that like if some block is used many times in a way that can make an analysis bad we may sometimes clone it let's say in a few different places so basically uh what are you talking about is some heuristics try to avoid the plastic explosion right this problem because it's a common problem in the state in the program analysis field if you try to build a concrete control flow graph yeah like the heuristics we have is that essentially a what helps us in the development in the VM byte code and especially in solidly produced code to uh to get a good control graph is that there are there is information about possible call sites let's say possible private functions and we use that okay we use the kind this kind of heuristics like we have a research paper that explains that in uppsla 2020. okay so um does that answer your question I think uh I guess we may have more discourse later but I have a second question so is that okay yes if you want to you you can get back to first question and clarify it like feel free to do so we have time okay that's cool so my quest second question is um uh because you tools relies on the symbolic execution right so uh as far as I know it's very uh you know it's very slow for example some other tools like misreal or Miss X they use the symbolic execution globally so the the performance is not very good so um my question is do you use it globally or you just use it use it on demand so our analysis engine does not really use a symbol execution but [Music] with so first of all like our whole pipeline like we run it on everything that's deployed because it can scale very well and what allows us to scale is first of all like the the fact that we use topic analysis essentially so for the compilation we get a coverage of like over 99 of the blood contracts and everything is decompiled on our site and for uh analysis we don't always analyze everything because you know on the blockchain there is a lot of past contracts that are not used so we don't analyze everything but we analyze what's like used in the past few months constantly so because we constantly improve the analysis and yeah static analysis and the techniques we've developed with maybor or some elements from symbolic execution so basically we try to have something close to a pointer analysis but the values are it can be arbitrary expressions and we give like very deep path sensitive information about where we were so this is a so yeah these kinds of techniques and the fact that we tune it a lot like we work with the latest contracts to ensure that it runs helps us to be able to decompose and analyze most contracts oh okay so basically you have a protein strategy and use the historical transaction to do that yes okay to to know which contracts are important to analyze basically okay got you thank you thank you for your questions thank you for engaging with the audience specifics and thank us thank you for asking amazing questions um please give it up for syphus

Automatic transcript — names and jargon may be misspelled.