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!
performConversionForTokens() with a path of different tokens. However, this doesn't contain an allowlist or checks for reentrancy.balanceOf for TONIC on the current contract. The sent in amount of TONIC is thought to be amount that the user now has, crediting them all of this.stake() part way through the execution of this, an attacker can send in tokens as part of the stake. So, they get counted both as the stake and as part of the transfer, leading to a double use of the TONIC. By repeating this over and over again, it's possible to steal almost all of the funds from the protocol.MarkerTransferAuthorization with an authz wrapped call. So, the modules bank, authz, auth and marker were the only possible culprits here.time.Now() value in Go. Yikes! A big source of non-determinism. When performing an upgrade, nodes that came on sooner were fine on these grants. However, some nodes that came on later after the upgrade would have been this grant fail! In the end of the day, this was actually an issue with the Cosmos SDK itself. transfer-encoding and the size of these chunks. So, with this, they had a potential vulnerability. After some effort with playing with these values, they got a crash. What was the crash about? The value 0x0a0d could be written to an arbitrary offset on the stack./bin/init binary, they found a signature check being performed but assumed more checks were in it. So, they patched the function do_halt() to not exit.0xXXXXX0a0d. With this return addresses, saved base points and locals did not seem like get paths to hit. So, they decided to target a heap address that was on the stack that contained function pointers.system function. Eventually, they got this working with a payload to run one of the limited commands in the shell. They eventually came up with a more complicated ROP chain to get a shell though.Gateway contract. requestRemoveMargin() it emits an event for a bot to see. Once the bot sees it, it will call finishRemoveMargin() with signed event data and a signature to finalize the request. finishRemoveMargin, finishUpdateLiquidity and finishLiquidate. In the former two, they have an internal function for checking the _checkRequestId to increment the nonce to prevent replay attacks.finishLiquidate(). However, since the position NFT would have already been burned then it would have failed anyway. So, no issue, right?cumlativePnlOnEngine field in the liquidate struct matches the requiredMargin field. Since the verification happened in the previous call, there is no validation on any of these values!abi.decode() didn't fail with the different data lengths. Overall, good finding with a fun write up!withdraw() to transfer ETH, the totalAssets were being updated after this call. So, the classic reentrancy was on!0xABAB.... It's possible to downgrade a user with a MitM to force this version of the protocol. Again, amazing.strstr function as well, so de Bruijn sequences can be used to make this even more efficient. There is a lockout for failed attempts here though.script-src to only allow content from their CDN. They removed the self from the list (which I thought would be fine on the page tbh) which removed some weird edge cases. In particular, mime sniffing issues from the browser and weird JSONP endpoints.object-src (used for emebeds) to not include self either. They removed this because of a person who found a CSP bypass from it. The hacker had found a content injection bug that allowed them to control the class attribute with some automatic behavior from JavaScript to fetch the href associated with the element. By doing this with a content sniffing issue they were able to get Flash code to execute within the embed alongside a Chrome browser bug. img-src to be much lower as well. Why is this important? Dangling Markup issues can allow for parts of a page to be sent in a URL if the source of an image isn't seriously considered. On a newer post they did, Cure53 found a way to abuse the dangling markup on Google Analytics and another website to exfiltrate information.connect-src restrictions what domains can actually be connected to for fetch, websockets and other things. This limits various attacks by inherently not allowing interactions with the outside world. form-action can be used to restrict where formed can be submitted to. Using password manager autofill or attacks similar to the dangling markup, this can be very useful. They have a few more restrictions on iframes as well, which is always a good thing.form-action was created as a directive in CSPv2. However, default-src doesn't cover form actions for some reasons. Overall, an interesting CSP bypass that will probably exist for a while.