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!
password_verify. This takes in the plaintext version of a password, alongside the salted and hashed password. cryp_blowfish.c, there is a line of code that will cut a salt short if it contains a $ inside of it. However, since this was a modification of the code and not an original implementation, the developer didn't consider the ramifications this would have down the road. This change is literally labeled "PHP Hack", which is awesome.strlen being used on a string that was assumed to have a specific length, which isn't the case. In some cases, this could even verify a password when it's incorrect. Pretty neat!write opcode is structured as follows: opcode|gpu address destination|value to write. Since we were getting an error when executing this instruction with the delay, the author didn't know how to debug this. The workaround was to use two buffers instead of one. By doing this, they could see where the inconsistency was occurring at. Since we can read both buffers, this is easy to do.0x7e. The hunch was that the GPU was reading data from the buffer from the previous use. The author attempted to replicate this by filling the buffers with a magic value. To their shock, their magic value appeared in their output! This means there is a major information disclosure big that can be accessed from Android applications.MIGRATE_UNMOVABLE must overlap with a kernel page. After some poking around, they found something that met their requirements. Some other shenanigans and Android kernel specific knowledge later, and they had a complete KASLR bypass by reading specific objects.burn in ERC20 is the destruction of a token; literally removing it from the total supply. Although this doesn't seem useful at first glance, pools rely on the amount of tokens in a pool to determine the price. The price isn't USD to token. The price is proportional to the pool ratio itself; trade 5 of token A for 2 of Token B.allowances. This allows other addresses to spend money on your behalf. The map for this is allowances[OWNER][SPENDER]. The check for burning as another user was written in reverse though: allowances[SPENDER][OWNER]. So, an attacker could burn tokens in an arbitrary account!burnFrom messed up the ordering. So, to satisfy the require, we must allow the pool to access our tokens.setActiveCurrency. This ensuring that there is no double counting of the current collateral.
setActiveCurrency() in the else clause even has a comment about "... so there is no double counting during FreeCollateral.". However, this function is ONLY called during the else clause and NOT the IF statement. As a result, the activeCurrencies field is NOT cleared. depositUnderlyingToken(), setActiveCurrency will be called for the account. To get two currencies to be active, we can call enableBitmapForAccoutn with a currency we do not care about then make a second call to enableBitmapForAccoutn after the deposit mentioned. Due to the logic error, the free collateral calcuations will run twice on the asset deposited: once for the bitmap and once for the activeCurrencies.depositUnderlyingToken() on the currency you want to double._mintShares() is called. If the ERC20 token has zero supply, then the minted shares are simply the amount of liquidity added. Otherwise, it mints the amount proportional to the percentage of the total liquidity.mulDiv(totalSupply,liquidityAdded,existingLiquidity). It should be noted that the division will round down. If totalSupply * addedLiquidity is less than existingLiquidity then this value could be 0.1 * $10K / 10,001. This will round down to 0.swap call, the address of the factory is used controlled. With proper input validation, this would be okay. However, this factory could return a fake token pair for BabySwap.allowance to themselves without checking the users underlying balance created a money duplication bug. This was done multiple times to drain the contract.NameRegistered0x00 has a nullbyte and terminates the string. By registering a name with a nullbyte at the end, it won't be a duplicate but it can be an arbitrary string in subgraph!