People often ask me "How did you learn how to hack?" The answer: by reading. This page is a collection of the blog posts and other articles that I have accumulated over the years of my journey. Enjoy!
MasterChef contract. By understanding this, we will be able to understand most in-moment math handling and most staking contracts. blocksSinceLastReward: The amount of blocks since the reward information has been updated. rewardTokensPerBlock: The amount of tokens that should be given per block.stakerShare: The percentage of tokens of the whole staked. Since this is Solidity without floats, there is using fixed point arithmetic.blocksSinceLastReward * rewardTokensPerBlock * stakerShare(BlockARewards / TotalTokensBlockA) + (BlockBRewards / TotalTokensBlockB) + ... (BlockNRewards / TotalTokensBlockN)
StakerAShareOnNtoM = StakerATokensOnNtoM / TotalTokensOnNtoM. This means that we're calculating the tokens we had over the timeframe of blocks and dividing this by the total tokens in this timeframe. This gives us the total shares of a user over a specific timeframe. RewardsPerShare instead of calculating the rewards per block for every user. This is because the RewardsPerShare is the same for every user. To reward a single user, we calculate the amount of shares for a given user. AccumulatedRewardsPerShare that is stored for the last time a user performed some operation. Using accumulatedRewardsPerShare - previousAccumulatedRewardsPerShare allows us to calculate the proper amount for this.
sid with SameSite=None and Secure. This request required a valid CSRF token though. postMessage call without an origin check; this is a pretty obvious bad code sink. The functionality was calling arbitrary functions from app window, potentially leading to XSS. However, they couldn't find an easy eval() or something else simple. APP.util.setCookie() allowed them to set arbitrary cookies on the various domains. Additionally, they found a powerful JSONP endpoint. The purpose was sending a call to a JSONP endpoint to lead an external script with the user choosing the domain. postMessage call to this, it would load inline JavaScript. How do we get a one-click interaction though? I don't believe that the postMessage call is accessible from other windows. X-Frame-Options: SAMEORIGIN options, which prevented framing. As an attacker, this can still be opened in a pop-up window to get a reference, which is news to me!postMessage call to get XSS via the JSONP endpoint. postMessage were defense-in-depth issues that led to the exploitation of this; this is why these small things matter. msg.sender. By using this, it will use the real msg.sender or the trusted forwarded from the SGN network.MsgEthereumTx. Prior to getting executed on the EVM, Ante Handlers are ran. These are functions that are run on each transaction and check the validity of a given transaction based upon the current context./ethermint.evm.v1.ExtensionOptionsEthereumTx option, it will go through a large list of decorators. But what if we use a different path? This allows us to execute the code that we want but skip the gas fees.send to one of the liquidity bridge contracts. This locks the tokens on that bridge then emits a Send event to describe the details of the transfer. This will be picked up by a SGN node to call MsgProposeUpdates to update the contract. MsgVoteUpdates, which consists of yes and no for active proposals. The sync module takes in votes and adds them to a structure. At the end of the block, the function iterates through the updates to ensure that all items passed with a 2/3 vote.EndBlocker function does not validate if somebody has voted multiple times. Using this, an attacking validator could vote multiple times. Yikes! Breaks the entire voting system. This results in directly lost funds, since they can spoof onchain events such as bridge transfers and much more.pausable, with automatic triggers to stop contracts. Overall, a fairly simple bug in complicated architecture.deadline. The transaction could wait in the mempool for a long time when trading is intense. Setting the maximum amount of time it waits in the transaction pool is important in order to prevent bad positions for users.block.timestamp instead of setting a real timestamp. This vulnerability ended up being a bad interaction with Uniswap if the transaction is left in the pool for a super long time.m_nMaxClients. Using this, an attacker can execute privileged commands on the server, such as quit. snprintf, which will truncate the string. So, we can bypass the filter!con_logfile writes to an arbitrary *.log file. This suffered from the same snprintf truncation issue, but on a write. This gave them an arbitrary file write vulnerability. -insecure flag. Using this flag, DLLs from outside the bin/ directory too. gameinfo.txt so that the malicious DLL is loaded on start up. All Source Engine games are just add ons to Half Life so this is common.amountOfX/TotalSupply). Since these tokens are pegged to each other, this can be used to estimate the amount of total value of underlying tokens in the pool. get_virtual_price() implements an oracle for the conversion rate. In particular, dividing the underlying tokens by the total supply will give a good oracle. This is used to estimate fee growth or estimate the value of LP tokens. totalSupply or amountOfToken for a brief moment? If we did this, then the function get_virtual_price() used by other contracts could cause major problems. In this case, there is a read only reentrancy bug in this. remove_liquidity() function is used to remove liquidity from a contract. This happens in a few steps:
burnFrom, which decreases the supply of LP tokens.totalSupply has already been changed but the amount of each token has not been updated yet. By executing other code during the fallback, we can interact with the contact while it's in this state. get_virtual_price(). Protocols that use this function can be manipulated with the following steps:
init script to be set to /bin/bash did not work. So, instead, they choose to modify the flash memory chip with their own version. They dumped the code, used unsquashfs to unpack the file system, backdoored it, resquashed it and wrote it back. bootdelay variable is used to determine how long to wait prior to booting into the OS. If this is set to -1 or -2, this check is skipped entirely. Practically, this means that it's not trivial to get into U-Boot shell. To bypass this, a forced error in the reading of flash will drop you into a U-Boot shell - this is called Pin2Pwn. Can we stop this!? You can't. bootdelaykey and bootstopkey are passwords for stopping/delaying autoboot. If you don't know these passwords, then you can't go into the shell (even with a glitch like before). This is simply a plaintext password in an ENV variable. By either reading this from the NVRAM or brute forcing the password, it's still possible to break in. bootstopkeysha256 is similar but a sha256 hash. bootargs for Linux are not trivial to modify.