In most cases, a vulnerable blockchain is nothing to brag about. However, Kudelski Security’s FumbleChain is just that, and they’re proud of it. FumbleChain is a purposefully insecure blockchain that encourages users to learn about blockchain security.
It contains a series of challenges that each demonstrates a common blockchain vulnerability. Once you solve the problem, you receive FumbleCoin rewards. Don’t get too excited, though; these coins have no monetary value. The real rewards are the skills you learn along the way.
Never a team to back down from challenges, we took our blockchain penetration testing knowledge to FumbleChain, successfully finding every one of its vulnerabilities. The following are our results.
WARNING: The rest of this article contains solutions to FumbleChain’s vulnerability challenges. If you’re planning on performing blockchain penetration testing on FumbleChain yourself, you may want to do so before finishing this article.
Vulnerability #1: No Input Sanitation Enables Replay Attacks
The first vulnerability we discovered in our blockchain penetration testing efforts was the potential for replay attacks due to a lack of input sanitation, particularly in the Blockchain.py file.
What should happen: When you initiate a blockchain transaction, the network checks the magic number of the operation against the magic number associated with the blockchain. If those numbers don’t match up, the transaction is invalid.
The FumbleChain vulnerability: FumbleChain isn’t correctly performing the validation of the magic number. Therefore, you can create a transaction on any FumbleChain fork and effectively copy it to the main chain. If the wallet in the main chain contains enough funds, the operation will still execute.
We were able to create a transaction involving a mainnet wallet on the FumbleChain testnet. Then, we copied information from the JSON response and created a raw transaction on the mainnet with that information. Because the magic number isn’t included when signing a transaction, we were able to alter the new transaction’s magic number to match the mainnet and replay the transaction.
After mining six blocks, we received our stolen funds.
How to remediate: FumbleChain needs to include the magic number when creating transaction signatures. Doing so ensures that the signatures will be uniquely valid on a particular fork, and only that fork. Additionally, FumbleChain should add more logic in the Blockchain.py file to validate the magic number of transactions.
Any Forkable Blockchain Is Susceptible
FumbleChain isn’t alone in this type of vulnerability. Almost every blockchain can fall victim to replay attacks if the right precautions aren’t in place.
Protection against replay attacks is especially vital in blockchain forks. When Bitcoin Cash forked away from the Bitcoin main chain, the development team needed to add additional information to transactional data as a form of replay protection.
Vulnerability #2: Improper Key Pair Generation Exposes Private Keys
Next, during our blockchain penetration testing process, we found that some FumbleChain wallets are cryptographically weak due to a key generation flaw. This vulnerability enables a malicious party to generate some wallets’ private keys from their public keys. With that information, you gain control of the wallet and its funds.
What should happen: There should be no possible way for someone to figure out a wallet’s private key solely from public key information.
The FumbleChain vulnerability: Certain FumbleChain wallets share a private number with other vulnerable wallets. We were able to capitalize on this mistake and figure out the private keys of wallets with which we don’t have ownership.
We first extracted the public numbers from two available wallets (N1, N2, and E) using the OpenSSL utility. Then, we found the greatest common divisor between N1 and N2 (p). Dividing N1 and N2 by p gave us the private number for each wallet (q).
Using rsatool, we plugged in N, E, q, and p for each wallet to obtain the private key of each.
How to remediate: The FumbleChain team should review its source code regarding wallet generation. Ideally, a public key modulus should never share a private number with another wallet. To prevent issues moving forward, FumbleChain could generate two wallets at a time, verifying that they don’t share a private number (i.e., the gcd(N1,N2) == 1). Then, provide one of those wallets to the user and discard the other one.
Airtight Cryptography Is a Never-Ending Battle
Cryptography is complex, making it a never-ending battle to protect it from ever-evolving cybercriminals. When implementing cryptography into your blockchain security system, it’s best to use tried and true methods and avoid rolling your own crypto (i.e., creating your own cryptography).
Additionally, you need to continually review your code to ensure that new mechanisms won’t have a detrimental effect on legacy code. Robust testing (both manual and automated), as well as sanity checks, go a long way in ensuring security as your product evolves.
Vulnerability #3: Transaction Retransmission Allows Infinite Transactions
Finally, our blockchain penetration testing revealed that you could retransmit an already successful FumbleChain transaction. Because the signature of a completed transaction is valid, the network automatically accepts the repeat transaction and adjusts the wallet balances accordingly.
What should happen: You should not be able to resubmit a transaction that had already been executed.
The FumbleChain vulnerability: In our blockchain penetration testing, we edited FumbleChain’s CLI.py script to create a custom function. The function targeted FumbleChain’s Echo wallet, a wallet that receives tokens and responds by sending back an equivalent amount.
Our malicious function first sent a transaction to the Echo wallet. It then replayed the Echo wallet’s reply transaction (sending tokens back to our wallet) in the next block. Because FumbleChain only checks for transaction uniqueness within a block, we were able to continuously execute the same operation with each new block until our wallet balance reached an infinite amount.
How to remediate: FumbleChain needs to add logic to its code that checks the uniqueness of transaction IDs against the entire blockchain, not just the block of the transaction.
Wallet Functions Are Just as Vulnerable as the Blockchain
Even if your blockchain is secure from a network, mining, and node perspective, the mechanisms with which those components interact still provide attack vectors.
Other than the preventative measures we’ve mentioned above, you should also implement stopgaps to limit the damage from an unforeseen attack. For example, FumbleChain could add an upper limit to the amount a wallet can hold. Doing so ensures that even if someone capitalized on this exploit, (s)he would be limited in the amount they could steal.
Our Blockchain Penetration Testing Discovers Even More
In our blockchain penetration testing process, we found two additional vulnerabilities that the FumbleChain team hadn’t created purposely.
Considering the looming threat of nation-state level actors with ample resources, we determined that the RSA 1024bit Asymmetric Key Encryption that FumbleChain currently uses is insufficient. Continuing to use that encryption method for private/public key generation is likely to expose wallets over time.
Instead, we suggest that FumbleChain switch to an RSA 2048bit encryption scheme, at minimum, migrating previous wallets to the new scheme as well.
Equally as important, we discovered that FumbleChain contains at least one denial of service (DOS) vulnerability. A malicious actor could overwhelm the system by mining blocks at such a high speed that it would overwhelm the other nodes. Testing this vulnerability was outside our scope, so we’re unsure of the impact that this type of attack could have.
A simple solution to this DOS vulnerability is to implement some single-origin block and transaction rate-limiting, although we would need to perform additional testing to see how appropriate this solution would be.
Think Like a Criminal
We were able to discover every FumbleChain vulnerability (plus two extras) because the blockchain penetration testing process forces you to analyze the network as if you’re the person attacking it. Just as with traditional penetration testing, it places you in the shoes of potential cybercriminals, providing you with the most effective way to keep your organization protected. Think like your attackers, and start protecting your blockchain today.