Yesterday, our team participated in Netcraft’s cryptocurrency capture-the-flag workshop, where we competed to earn as much “Netcoin” (a fictional and insecure cryptocurrency) through every possible exploitation tactic we could come up with. Our team ended up taking first place, and I enjoyed the whole experience from start to finish, especially talking to the other teams and discussing what techniques they used and how they approached the challenge differently to us.
Teams were given Debian Linux servers with the Netcoin daemon (riddled with dozens of obvious and some less obvious vulnerabilities) pre-installed, and tasked with earning coins through any means necessary: finding exploits, optimising their mining, patching vulnerabilities, or even coordinating 51% attacks.
Our strategy
While we could have easily focused on single approaches like optimising our mining algorithm, our team quickly decided on a multi-pronged strategy to maximise our netcoin gains:
Hashing functions
Our first move was upgrading the security infrastructure. We immediately replaced the insecure MD5 hashing algorithm with SHA-256.
evil.sh
This was our secret weapon, if you will. We wrote a tiny bash script (which was innocently named evil.sh) that continuously scanned for insecure wallet addresses belonging to other teams. Every ten seconds, the script would:
- Identify open/vulnerable wallets (if teams hadn’t changed their algorithms, all the possible wallet addresses were 2-byte long hashes, intentionally short enough to iterate through)
- Empty their contents, and
- Transfer all of their funds to our own various wallets
The automation gave us a massive advantage. While to begin with, we manually hunted for vulnerabilities in other teams’ wallets, having a systematic approach running 24/7 alongside our miners gave us a constant flow of income.
Spreading our coin across wallets
Our rank on the (very publicly displayed) leaderboard made us a big target. To protect our holdings, we had to quickly implement some defensive mechanisms:
- Every few seconds, we generated new wallets with 2048-bit keys and
- Automatically distributed portions of our holdings across these wallets
Don’t put all your Netcoin in one wallet, as they say.
Mining optimisation
Another member of my team focused on optimising our own cryptomining:
- Multi-threading the mining functions: The original implementation was single-threaded, despite the linux machines having two cores
- Removing artificial delays: Found several
sleep()calls (thanks, Netcraft :p) that were throttling our mining performance
Our optimised miners were soon generating blocks significantly faster, giving us a solid head start no matter how quickly the other teams caught on.
Tech stack that Netcraft used
During the event and afterwards I was very interested in exactly how the system was built - the architecture was honestly a pretty cool way to learn about cryptocurrencies from a security perspective. Built in Go (I had to give myself a speedy introduction to Go on the fly!), it used SQLite for blockchain storage and exposed both peer-to-peer and RPC HTTP endpoints. The codebase had several (intentional) vulnerabilities that were fun to exploit:
- Weak RSA key generation (we exploited short keys using the provided
factorkeytool) - Insufficient input validation on transaction endpoints
- Poor access controls on wallet management functions
- Timing attacks possible on various operations
Final thoughts
The highlight for me was watching my baby (the evil bash script) run and start pulling in funds for the first time - it was pretty incredible to see our strategy pay off on the leaderboard in realtime.
I genuinely enjoyed the workshop, and hugely appreciated the opportunity to meet the great team at Netcraft.
Huge thanks to them for organising and pulling off such a well-designed challenge. The friendly-but-competitive dynamic combined with the fun concept and real-world relevance made this one of the best workshops I’ve participated in.