← All talks

Permanently bricking smart contracts for fun and profit- Ashiq Amien

BSides Cape Town24:1967 viewsPublished 2023-09Watch on YouTube ↗
About this talk
BSIDES CPT 2022 Track 2 Permanently bricking smart contracts for fun and profit - Ashiq Amie
Show transcript [en]

sweet cool can you guys hear me I cool thanks for coming to my talk So today we're going to speak about a special bug that affects a lot of smart contacts and there was over one billion dollars at risk during its peak and this bug was also awarded the world's largest bug Bounty ever paid ever so let's get into it so just a bit about myself I'm ashikamin um I recently became independent a few months ago but before that I was working at Ironside over two years that's where I learned about smart contracts and I think some of the isider guys aren't on so if they are you should definitely speak to them they're super duper talented and produce like the most amazing work so shout out to ayersiro um in my spare time I like to play ctfs and I play Under the team name Twisted steak sandwich the team is just me I'm the whole team but I don't play for points so I just do it for learning it's just for fun and when I do have anything like noteworthy I will write the bunch of my blog so at ashik.co.za you can see all of my CTF blog posts and there's also just social media handles if you guys are going to get in touch so Twitter is probably the best um I don't really like this code this code is full of spam so I'll probably miss your message but Twitter is pretty good um beyond that I also post about my research so a lot of my research is about bug bonus so during my time at isilo I focused on bug disclosures and kind of posted all of the different bugs that I've disclosed over time so today we'll be speaking about one of the bugs that is closed and escalated as well so cool the bug is about booking smart contracts and in particular speaking proxy contracts but to get to it I'm kind of going to build up all the requirements that we need to talk about a bit tonight so I'm going to into a small contracts into the requirements that we need for the bug speak about the exploit speak about the impact and then talk about escalation and another thing we can talk about impact and any of the remediation cool cool so what a small contracts man so IBM is a smart contracts or programs on the blockchain and they run in three determined conditions are made but I mean you can Google it and you'll find 10 000 definitions but basically they are blockchain programs right but what does that mean so usually people talk about smart contracts as analogous to vending machines so the reason they use this analogy rights because vending machines don't have this idea of a con right so on their own vending machines don't do anything so until someone comes up and puts some money in selects an item then this is some kind of output right so smart contracts sort of Behaving the same way there's no notion of con job so they won't act on themselves right there has to be some interacting with the contract before something happens so there's usually some kind of external either human being or even just a script that's running more importantly a smart content has two very important things and that's just code and state so the code is compiled by code but you can write it in any language so solidity Viper and there's a couple old ones too but the state yeah so the state is the other part of it and the state is basically the storage of the contract and that's just holding all the states variables so anything important let's do it like metadata or anything else right cool so because smart contracts live on a blockchain and not just on a server somewhere it inherits a lot of properties but the main three ones for today are irreversible transactions so when you interact with any smart contract or anything on the blockchain there's no way to reverse the transaction so once it's done it's finalized right so if you are an expert at blockchain you will argue with me and say that's not true because you can technically Fork the chain and pay someone pay all the miners to get it right but like for today's purpose it's not deleted applied so we can just call it irreversible and then the next property is atomic transactions and this just means that transactions happen as is so it either happens altogether or none at all right and this is very important so if your code hits the revert at some point later in the stack the entire thing goes divides back basically and there's no State changes committed so that just means that everything happens at once or none at all and then the last property is immutable code and this is the most important one for today so immutable code just means that once you've deployed your bytecode there's no way to change it right it's there forever and it's just never going to change you could hard code some parameters to pause your contracts but there's no way to do anything else there is a special Edge case of immutability and that's called self so there is an instruction on the blockchain that you can use specifically for ethereum in ethereum style chains where you could wipe out all of the state and wipe out all of the code so in that sense it's not super immutable because it's either on or off you can edit the code so I mean if you're a Dev which I think some of you guys are you might be thinking like what the hell who wants to write immutable code that's like very scary about so this has been an issue I mean I try to get this graph where I'm trying to show that there's been three billion dollars worth of damage that's already been taken place because of invisible code but I couldn't get an exact estimate because it's also things like private key compromises and insider trading so it might be higher but the point is that it's a high number like in the billions um so there's a very real need for upgradability but unfortunately this is a double edged sword because upgradability comes with its own issues that cost even more money to be lost so to talk about availability and how it works we have to first talk about how smart contracts communicate with each other at all right and the first way is a DOT call so that call works in the same way you might think normal computable computer program works and let's just buy one contact calling another one and the state changes are committed to the call to the contract that we called right uh pretty straightforward so as the example in the slide if you had a call transfer the token balance on contract B state would be updated the next goal is delegate call and this is basically what's called code copy right so instead of the state changes Computing on the initial contract so the Target contract is completed on the initial contact right and what this means is the code at Contract B is copied and those State changes applied to contact a so you can just think of delegate call as copy right and this two things we can use together and form some kind of mini architecture and this will be enough to have an upgradable pattern right so what we do is we separate the byte code from the state by using two separate contracts with respect one or the other right so we call the proxy contract the one that holds the state and the logic contract the ones that all the byte code so if at some point we find some buggy issue in the logic contract we can upgrade the logic contract by simply pointing to a new logical contract at the bottom of the slide this is like a tiny diagram cool so those are two ingredients that we have we have upgradability and we have self-destruct but the last ingredient that we need for our bug is just to talk about initialization so when you deploy a smart contract there's a construct that runs which is the normal function that you consider in a normal computer programming in computer programs but in this case because State and the logic are separate we need to initialize the foxy contract simply so we need to assimilate a Constructor to get the state across so the way it works we just hard code special function it makes sure it only runs once and usually just like a normal Constructor there's access control that happens it gets provided to different users when the initialization takes place cool so this is the first iteration of the bug and before we talk about the diagram and how X actual exploit works we need to just talk about the assumptions that we need to make so in this case we need to assume that our logic contract has some kind of delegate call right so just taking on that assumption there's an exploit that you can do so one is that we check if the logic contract has been initialized because if you remember the state of the logic contract is not important in our architecture at all so we can additionalize the logic contract get any of the access consoles needed if it's been initialized and then we can deploy our own contracts because it's permissionless anyone's allowed to deploy contracts and in this context we can include a self-destruct instruction so what we could do is using this delicate call that be assumed we could upgrade the logic contract and destroy it right so what does that look like so once the delegate calls performed our bytecode ethology contract is wiped the logic state is wiped so this just means that the proxy points to nothing and this is the first iteration of the brick but this is just temporary so it's only the first iteration and the Plexi administrator could come in and say hey I've seen the brick it's kind of an issue but no problem we've included upgradability on purpose so we can just go in and upgrade the proxy point to a New Logic sorted out cool so let's just chat about impact even though it's only a temporary brick it's still pretty bad so the logic contract is permanently destroyed right once it is destroyed there's no way to get it back because transactions are irreversible as we discussed the assets that are on the proxy itself so if you have however much billion dollars worth of tokens those are not accessible at all while the proxy is pretty so until an administrator comes through and upgrades the contract it's locked in and this could also be made more severe if there's a time lock right because we have this sort of trust admins to not just hot swap our logic at any time so react sometimes there's a time lock involved way you have to commit a code for maybe seven days or 14 days and people are allowed to check out what the code is doing before it's applied so your assets might be locked up for a little while and the next thing is a proxy knob so when the proxy is damaged and just becoming a brick there's no hard-coded reverts right so the code just nops through and that just means that any calls to the proxy itself after the brick means that there's just nothing happening so if axis controls are relied on the proxy then reaches bypass those access controls and this happened in rbv2 but and the last one is just reputational damage which isn't like a real big issue but I mean I wouldn't trust my money it's once this code conflict right cool so let's talk about profit the first profit mechanism is exploiting the knob so in other V2 their contracts are vulnerable to this exact bug and if it was exploited it is possible to steal a couple million dollars at a different contract because there was an up through the access control uh but it didn't have happened though because there was someone disclosed responsibly there was actually no exploit so all good the next way is shorting the lock token so if your contract has a bunch of native tokens ftt token or any other token you could short the token beforehand exploit the contract and then of course panic and you'll make a lot of money this also has never happened before but it is some way to make money and then the best case is responsible disclosure which is sort of what happens in each case with this bug right so for rbv2 in the example the Whitehead got paid twenty five thousand dollars for disclosing which is not bad it's a sort of on par with critical Bargains of web2 right cool so we already spoke about the admin upgrading to a fresh logic contract but if you're a bug Bounty Hunter you could think cool what are some of the things you could do to fix the bug if you find it and one way is to just initialize the contact directly without using your malicious contact right so that just means we're going to pick the contract as is but not in a malicious way and then petrifying the logic conflict so that just means as you deploy the contract The Constructor automatically initializes the logic so that no one else can reinitialize it Okay so we've done good we made twenty five thousand dollars we could have entered a couple million from being stolen uh the admins were annoyed but they've upgraded the code their code but we can do a little bit better so when I say a little bit better there's a special branch of proxies where we can escalate the template with permanent one and that's the uups proxy so how does it work it's very similar to our original proxy but with a couple differences and the main idea behind it is to highly optimize the proxy itself and what that means is that the upgrade mechanism is moved from the foxy to the logic so this just also means that proxy itself has no right functions at all so the only way back to the state is to delegate delegate code into the logic concept and everything else sort of works as is the initialization provides access control as usual um and in the main point of the ueps proxy is that the upgrade itself has the liquid visual scene so this is what the upgrade mechanism looks like and only two main steps one is to check that we have authorization to perform an upgrade and the second one is to perform the upgrade itself right so authorize upgrade once initialized you get those controls to do it cool looking at the upgrade mechanism we can see this delicate call right in this delegate call is allowed to run at any time provided just a bit send some data in and this just means that anyone that upgrades can always perform a daily format and if you remember this is performed on the Logic contact cool so the actual exploit for permanent brick performs in the exact same way as the previous one where if it's not initialized you can initialize it with our own malicious contact and call a self-destruct so everything looks the same but the differences are in the way the actual impact works so part of the impact is that the proxy now points to a logic that is permanently destroyed and the proxy permanently points to nothing which means there's no strain changes it never be performed again so any of your assets are gone forever right cool and updated impact so one of the main things that's different is that the proxy itself points to nothing permanently the similar impact is that the logic contract is permanently destroyed and the third is that your assets are locked forever so if you have a couple hundred million let's go unfavorable and the unbox synops are working in the same way too cool so when I was working at iocyto I disclosed this bug to five companies two of these were not mine but two of them were also undisclosed so I just hot swapped them with other pictures on the top right hand side is from ddub and at the bottom is some teller and just on these five contracts alone we managed to save over 15 million dollars from being hacked right and at the time uh I thought cool this is probably a bit more of a widespread issue so I spoke to Kyle it was my boss at the time and we decided to escalate this issue a bit further and rehearsed a meeting with open Zeppelin which is the author of the ueps proxy and when I spoke to them we just told them hey you know look we found these five contracts that might be an issue and they said yeah actually someone came to us a couple days earlier they found the same issue and we've started the remediation process and that process was demonstrating every single blockchain and they found 150 other contexts they were vulnerable uh so luckily they found it right but what did they do they detected all of the contracts across different chains they updated the source code to include a PhD file logic so that all of it is fixed in the future and they've monitored their solution so basically every time there's a new deployment they will check whether or not they're vulnerable and just fix the vulnerability as insights of favor so you might be thinking will be done right like everything so that there's just no more bugs they've detected everything on every chain source code is updated safe monitoring for news vulnerable contracts surely there's nothing else and simply it was just one more bug right there was one more and that affected wormhole so Wormhole was vulnerable to this exact bug in a slightly nuanced way we're an anonymous Whitehead found 700 billion dollars at risk and just for the disclosure alone they got paid 10 million dollars I wasn't the Whitehead they got the 10 million if it was me I wouldn't give this talk I would be on the beach somewhere or something but yeah cool cool so that's it for me the last couple takeaways is just that part of the reason this bug slipped through everyone was that it wasn't a code level bug so all the top auditing firms trailer bits open ziplin everyone missed this bike because it is a state dependent bug right and what this means is people understood of looking one way and no one is looking the other way so if anyone's interested you should 100 start learning how smart contracts work and I'm sure you could find some of your unbox cool I hope you enjoyed the talk oh happy take any questions too 100 so there's a bunch of different online materials I can send you a list personally but I've mainly focused on training from the security side so there's some war games you can learn about solidity and you can learn about how vulnerabilities work on solidity and plenty of ctfs for sure ctips can definitely upscale and find these bugs for yourself okay yeah cool so the question was is there any way we could find these bugs automatically and always remediate them as he is yeah so not right now not that I know of any the idea is mostly Grassroots so as bugs are discovered they usually come up with blog posts and talk about how the bug was discovered how it's intermediate it what to do next and unfortunately most people don't like to disclose their bugs too but I've worked with people and they've asked me very specifically did not publish a certain bug that I'm sure affected another content so there's no real easy way unfortunately but hopefully like with incentivizing like 10 million dollars worth of bugs I'm sure it'll come out so yeah not at the stage yeah I mean I think the nice thing about bhagban is is that you can just drop most of your assumptions about any kind of library or any contact lens if you think this one thing is secure it's it might not be right I mean Wormhole had 700 million and looking at Walmart on its own I might think cool 700 million is quite a lot of money I'm sure it's safe but they got act three times for 300 million in a different case so you can start anywhere you want to leave and I think the main thing is just to do some upskilling in the beginning for genetics and once you're comfortable with that 100 you can just go whatever you feel comfortable with foreign yeah absolutely I mean the main thing is that different functions have different access levels right different axis controls you don't want anyone being able to upgrade the contract or pick your content right so you can definitely pick in Access Control for certain cases for certain accounts but not everyone does this and that's why they get hacked and that's why this three billion dollar is gone but yeah I mean the code is quite genetic so it's quite granular in the sense that you can hard code any kind of Access Control that you want and prevent certain messages and prevent certain calls or delegate calls or any kind of message you want but you'd have to hard code that in depending on your needs cool thanks guys