Resources

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!

CSP Bypass Unveiled: The Hidden Threat of Bookmarklets- 1185

socradar    Reference →Posted 2 Years Ago
  • A bookmarklet is a primitive version of a browser extension. It's a simple version of a browser extension that can contain JavaScript code. Users can add bookmarklets by creating a bookmark, pasting the bookmarklets code as a URL or dragging/dropping the link onto the toolbar.
  • When the CSP came out in 2014, the idea was that the bookmarklets were going to die. However, this never happened, with references in the RFC for CSPs ignoring addons. Regardless of implementing a CSP or not, the bookmarklet can bypass this protections to interact with websites.
  • These bookmarklets were used for phishing attacks. In particular, Discords in the cryptocurrency space were being hit by these attacks. These attacks worked by asking users to drag a button to their bookmarks bar. Once this happened, the JavaScript within the bookmarklet code can be accepted.
  • With the admins knowledge within the account, the bookmarklet discreetly retrieved their Discord token when it was dragged, subsequently transmitting it to the attacker’s website. This led to posts on Discord channels with more malicious links and bookmarks.
  • Overall, an interesting attack vector to consider; I had no idea that bookmarklets could execute code like this. I'm sure we'll see some response from the browsers soon.

CosmWasm allocate stack overflow- 1184

claudijd    Reference →Posted 2 Years Ago
  • CosmWasm is a smart contract platform that can be used on Cosmos. This allows for a similar interaction of Solidity based smart contracts on the EVM.
  • Being able to find a denial of service (DoS) within a smart contract platform would be catastrophic. It could be used to stop the chain altogether for each node that was running. To me, it's weird that the virtual machine running the code wouldn't handle the error, toss out the error and move onto the next transaction though.
  • CosmWasm has a several runtime imports. This functions exist to offload expensive operations (like cryptography), perform validations and write state changes. All of these functions use a helper method called write_to_contract() to write error messages to the WASM address space.
  • To do this, write_to_contract() calls allocate. This function allocates a large block of memory in the address space. Normally, this is a standard library from CosmWasm but can be overwritten by a developer.
  • A classic problem that developers run into is recursively calling functions; this creates a stack to deep, otherwise known as a stack overflow. By adding a call to addr_validate() within our custom allocate() function, an infinite recursion call can be created.
  • This is a really simple bug that has horrible consequences. I bet there are many other issues in the layer 1 eco-system on newer blockchains. Just got to go look!

Bypassing SELinux with init_module - 1183

Sean Pesce    Reference →Posted 2 Years Ago
  • Security Enhanced Linux (SELinux) is an added layer of security to the OS kernel. Using it, access controls can be put on applications, processes and file on a system. Just because you have root doesn't mean you've won with SELinux.
  • The author of this post had a reverse shell on the box but had some serious restrictions in place that prevented exploitation. SELinux tools like getenforce were removed as well.
  • The SELinux is just a list of rules for the processes other actions that can occur. What if we could load a kernel module? The call init_module was restricted but finit_module was not! They are the same exact call except one takes in a file and the other takes in a file descriptor.
  • Calling finit_module allows the author to get into the kernel and disable SELinux. They had to write a custom loader for this though, which is interesting. Overall, an interesting bypass for SELinux.

Catch me if you can!- 1182

Red Guild    Reference →Posted 2 Years Ago
  • Solidity has error handling like most languages do. It looks similar to JavaScript with try and catch blocks. The docs can be read at here.
  • In the initial example, the author gives a fairly simple code for the try with 3 options for the catch. First, catch Error(...) catches a revert from the external contract with a particular reason string. Second, Panic catches a serious error like division by zero, an integer underflow or assert.
  • Finally, there is catch (bytes memory) that will catch all other unhandled errors. So, what if we could cause a denial of service by triggering one of these outcomes? Or, if we could bypass the checks implemented in a specific catch but not another? Let's hack things!
  • The first option that the author considers is a wrong data type. Naturally, the compiler makes an assumption that the proper data type is returned. When the data returns uint256, it will use the address or any other data that is provided.
  • The next case the user considers is returning data from a different location, such as dynamic arrays and strings. In the case of the string, the return value is 32. Although the author doesn't say this directly, I'm guessing this is the location of the dynamic byte array in the return data.
  • What if no data is returned at all? The EVM returns an error that there is an odd-length and the argument is invalid. Since there is no data being sent back, this triggers the general catch case.
  • What else can hit this catch? An empty fallback or executing code at an address with no code. Overall, an interesting article on the intricacies of try/catch statements in Solidity. If errors are not handled properly, it could lead to security issues.

A Mathematical View of Automated Market Maker (AMM) Algorithms and Its Future- 1181

AnchorDAO Lab    Reference →Posted 2 Years Ago
  • The article goes into the finance between many different DeFi algorithms. This is a large article with many protocols in it, including Bancor, Uniswap, Curve, Clipper and more.

Why DeFi is Broken and How to Fix It, Pt 1: Oracle-Free Protocols- 1180

Dan Elitzer - Nascent    Reference →Posted 2 Years Ago
  • Decentralized Finance (DeFi) is great eco-system for opening up everyone to many financial instruments. You know what's not great? DeFi hacks. A large percentage of these occur from manipulating the oracle or pricer of the assets in some way to purchase/sell assets at a bad price for the other party. This article talks about how to fix this problem.
  • First, the author mentions primitive protocols. This is contracts that have no governance, no upgradeability and no oracles. Why? If the main contract gets manipulated, then everything gets manipulated, since it's an underlying protocol for everything.
  • The argument is that if everything is self-contained, then oracle manipulation from other protocols subtleties is not possible. The only true example of this is Uniswap but it's now upgradable, which is a double-edged sword.
  • What about lending protocols? There are several cases of lending protocols being being oracle-free. Instead of the collateral factors being set by oracles like Chainlink, the lenders are responsible for evaluating the risks and deciding how much collateral they want from the borrower.
  • To me, this feels like a cop out though. The safety of the protocol goes onto the lender instead of the protocol. If a bad rate was set by a lender, it would immediately be swept up and stolen. The solution to this is having a good user interface that sets these automatically. How does it get these quotes though? A price oracle, but off-chain, which prevents serious manipulation.
  • The article is a tad odd to me but made some good points. Oracles cannot be manipulated if the values are set by the lenders. By having this off-chain, a subtle flaw in a contract doesn't destroy the whole eco-system. Thanks for writing up your thoughts friend!

Cross-chain re-entrancy- 1179

Mateocesaroni    Reference →Posted 2 Years Ago
  • Reentrancy is a fundamental attack in the Solidity security space. This is when a user can recursively call a contract while it has not had it's state fully updated. Developers should follow the Check, Effect, Interactions (CEI) pattern. However, the term cross-chain caught my eye for this post.
  • The application the author was testing was a cross-chain NFT contract. Naturally, NFTs should only exist on a single chain at once. So, verification has to be done on both chains before minting.
  • To send funds from one contract to another, a bridge is needed. Since the contract owns the asset, it can mint to create an asset or burn to remove it from existence. Then, using a proof, the other chain would know whether we owned an asset on it or not.
  • The code for the mint function did not follow the CEI pattern. The increment should occur before the call to _safeMint. This worked as follows:
    function mint(address to) public returns (uint256) {
           uint256 newWarriorId = tokenIds.current();
           _safeMint(to, newWarriorId); 
     
           tokenIds.increment();
     
           return newWarriorId;
       }
    
  • The _safeMint() function has an external function call for onERC721Received inside of it. Since the CEI pattern is not followed and the contract is not using the standard library for preventing reentrancy, there is a major problem.
  • How can this be exploited? If we simply call the _mint function again, it will fail because the token id wasn't incremented and already exists. However, there are other functions within the contract that could be interesting to us.
  • The function crossChainTransfer() is used to send the assets from one chain to another. Calling this with a particular token ID will send the token from one chain to another.
  • Since the ID is not incremented until after the mint call, we can exploit this to get two copies of it.
    1. Call mint() with the attacker contract as the recipient. NOTE: The ID hasn't been incremented.
    2. Re-enter the contract to call crossChainTransfer to transfer the new id to chain B.
    3. Call mint() again from the recipient contract to mint the same NFT once again.
  • Cross-contract reentrancy is a little bit deceiving but technically correct here. Overall, a usual bug class exploited in a unique way!

Polygon zkEVM DoS Bug- 1178

iczc    Reference →Posted 2 Years Ago
  • Since Ethereum and other layer 1 blockchains are slow and expensive, there are many layer 2 (L2) protocols appearing. The idea is to roll all the transactions on the L2 EVM into a single transaction on the L1 EVM.
  • To get assets on the L2, a bridge is used. Practically, this is done by locking the assets on the L1 then submitting a Merkle Proof on the L2 to mint the same amount of tokens that are locked in the L1. Any user can call the claimAsset(), but it always goes to the proper user.
  • While reviewing the code, they noticed that the claimAsset() was built to be gasless (free). This is because a new user will not have any assets on the L2, since they are currently transferring them over. Because of this, a malicious actor could send lots of invalid free claim tx's to cause a DoS. Well, not exactly.
  • To prevent a denial of service attack the claim tx is validated before it's put into the pool. This is a good remediation for this exact problem; great job by the development team for thinking of this in advance. Next, the author pulls up the code to look for logic flaws.
  • The code below is the logic explained above. If it's free and the execution reverted, then revert the transaction.
    isFreeTx := poolTx.GasPrice().Cmp(big.NewInt(0)) <= 0
    // if the tx is free and it was reverted in the pre execution, reject the transaction
    if isFreeTx && preExecutionResponse.isReverted {
        return fmt.Errorf("free claim reverted")
    } else { // otherwise
       ...
  • There's a subtle flaw in the code above though... the transaction can have gas! Since the revert only happens when the transaction is free, we can send very little money to put the transaction into the queue unexpectedly. This bypasses the pre-execute check on the claim tx, leading to the earlier denial of service vulnerability.
  • Overall, a pretty interesting bug that required a deep understanding of the application and the protections in place. To remediate this bug, they removed the special gas logic for claims. I'm unsure how this remediates the issue and still allows people to claim stuff from the L2 for the first time though.

Who crashed Junø?- 1177

Todd G.    Reference →Posted 2 Years Ago
  • Juno is a proof of stake based blockchain built on Cosmos and CosmWasm. While going through an upgrade of the eco-system, a bunch of issues were occurring... forks, lack of consensus and many other things. What was going on?
  • In 2021 the Terra blockchain was dealing with the same issue. What was the problem? Different versions of libc were outputting different gas calculations. The solution? Statically link the same libc version into the binary so that everyone can use it. This didn't work though. Hmmm.
  • At this point, they had attempted to role out the static version of the binary but this didn't work. They stopped the chain, told everybody to stop and decided to triage and analyze what was really going on. Sometimes, taking a step back is the best way to move forward.
  • The author of this post decided to review the pending transactions of their own validator's memqueue. While doing this, they noticed a weird transaction that was a call to a CosmWasm contract with some indirection. When they started reviewing the state, they noticed that the chain halted while changing the name. Why did this occur?
  • Every single node that the operator queried had a different name field. In particular, it had split into 125 different networks! This was at the fault of CosmWasm and led to them not reaching consensus. This vulnerability is known as indeterminatism; this is when the operations being performed do not have a deterministic path, leading to rapid forking.
  • This is not the end of this though. More issues were still occurring. While trying to get a node up and going, they kept going down with a very similar looking transaction. It was another known CosmWasm non-deterministic bug. The bug a non-deterministic ABCI query being made from a CosmWasm smart contract.
  • Overall, an interesting lesson on non-deterministic behavior on blockchain drastically affected the software. Thanks for the good write up!

Cosmos-SDK & IBC Vulnerability Retrospective: Security Advisories Dragonberry and Elderflower (October 2022)- 1176

ebuchman    Reference →Posted 2 Years Ago
  • The Binance Chain IAVL Merkle Tree hack gained from flags on security issues within the Cosmos SDK. As a result, the developers started diving into the code base to look for further issues. From this, they came to two more vulnerabilities: dragonberry and elderberry.
  • InterBlockchain Communication (IBC) is the protocol used to communicate across blockchains in the Cosmos ecosystem. IBC has a user configurable timeout mechanism that allows for reclaiming funds in the event that a packet is not relayed on time.
  • The ics23 proposal was all about a binary representation for merkle proofs. The vulnerability appears to be in the original implementation of this proposal. According to the advisory, there was a way to forge the proof. Since this has to do with money, an attacker could have used the bad proof to iteratively train the ICS-20 escrow accounts of every user.
  • To make this transaction harder to find, they added the entire file with the included changes. Although I couldn't find the actual bug in the implementation being used, looking at old and update.
  • The second vulnerability was within the AuthZ module. It was found by multiple parties at once independently from the Cosmos team. The Cosmos SDK uses ValidateBasic() to validate that a message is valid. However, the module was missing this check, leading to invalid state transitions being possible. This would have allowed an attacker to manipulate a market in strange ways.
  • Overall, I wish we had a better picture of this vulnerabilities and how to exploit them. It's super interesting to see these issues come to light all at once within the Cosmos ecosystem though.