author: Nathan Acks
date: 2022-08-12

Mostly DEF CON workshops today. Mostly.

Ghidra and the Commodore 64: Why Understanding Old Malicious Software Still Matters

Commodore 64 Viruses

Viruses in the Commodore 64 era were more about showing off or making some sort of social or political point - because there was no coupling between financial and computer networks then, there wasn’t really any opportunity for financial motivations.

There are only 7 known Commodore 64 viruses. All have been analyzed at this point except for the Bu£a (also written as BuEa and BUEA) virus.


The Commodore 64

Used the MOS 6510 CPU (specifically the 6502 variant) with a 1 MHz clock and 64k of RAM. Similar chips were used for the Atari and other computers of this time.

Variants of this CPU are still in use, though the form factor is very different now.

Mass storage was handled via tape (basically audio tape) or floppies.

As it turns out, the C64 expansion floppy drive had an additional 6502 CPU. This CPU could interact with the main CPU; while slow (the two pieces of hardware were connected via a serial capable), they could actually coordinate. Essentially, a C64 with a floppy drive was a primitive dual core system!

The term “kernel” actually dates from the C64 - KERNAL was the C64 operating system call. This functioned more like a modern BIOS than something like the Linux kernel, however.

The C64 supported BASIC, holding code in a special memory location.

Floppy disk tracks for the C64 designated different purposes to different tracks: Tracks 1 - 17 held file data, while track 18 functioned as a file table.

The Bu£a Virus

There are two know variants, identified by the 6.12 and 6.32 version strings.

When run, the visible impact of the Bu£a virus was some visual glitching and then text corruption. In the background, however, Bu£a opened a connection to the C64 floppy drive, copied its code to the drive’s memory, and transferred its execution to this new copy.

Copying itself to the C64 floppy drive was a way for Bu£a to maintain persistence, as the C64 chassis and floppy drive were separately powered.

The copy of the virus on the drive then waits for a file open event; when one occurs, Bu£a writes itself to the end of track 18 (if there is enough contiguous free space, which was common as the last 3 blocks were typically free). It then changes the pointer to any executable files on the disk to point to the virus code on track 18. This ensures that all executables on the disk now run virus code, though no data is actually overwritten by this process.

If the virus doesn’t find an executable or detects that track 18 is already infected, it just remains dormant (I think… the people behind me were talking, and I couldn’t quite make out the speaker).

The entire virus fits in 700 bytes.

Picking Pockets, Picked Apart

You really need a distraction to pick pocket. Generally by talking to them.

“This is the weirdest game of improv you’ll ever do.”

Try to avoid using your thumb - grabbing with your thumb takes up too much space.

Friction is what causes people to notice their pockets being picked.

A big opportunity is when someone lifts their arm - it opens up a lot of opportunities and moves the target away from the body.

Phones are designed to go in and out of pockets very easily.

Think of pick pocketing as a puzzle.

“Your field of attention is only so big. My job is to section off your attention to make it easier to borrow things from you.”

From Zero to Hero in Blockchain Security

Installation Notes

Add $VIRTUAL_ENV/node_modules/.bin to the PATH set by the virtual environment.

Brownie downloads the v0.6.12 amd64 solidity compiler (solc). I haven’t been able to successfully build older versions of solc on the Kali Linux Raspberry Pi installation, but I did manage to find a repository with aarch64 builds of solc. Is it safe? I dunno… But I’m kinda out of ideas. YOLO energy.

mkdir repos
cd $HOME/Repos
git clone
rm -rf $HOME/.solcx
ln -sf $HOME/Repos/solc $HOME/.solcx
chmod +x $HOME/.solcx/solc-*

What is the Blockchain?

The correct block hash (on Bitcoin?) is the first once that begins with the current nonce.

All tokens (except core network tokens like ETH, SOL, etc.) are defined using a smart contract.

Gas price depends on the complexity of the transaction; for smart contracts, this “complexity” is dependent on the complexity of the functions used in that smart contract.

Unless addressed through a proxy (how does this work?), smart contracts are immutable once uploaded. Subsequent versions of the smart contract get new addresses on chain; getting your users to upgrade requires persuading them to use the new contract address rather than the old one.

Blockchains are very vulnerable to race conditions. In particular, it’s often (in a probabilistic sense) possible to beat-out a pending transaction by paying a higher gas fee.

Smart Contracts

Smart contracts for Ethereum can be uploaded using the web-based Remix IDE, which is provided by the Ethereum Foundation.

Solidity has elements of both JavaScript and C++.

Until v8.0.0, the Solidity compiler was vulnerable to integer over- and under-flows.

Sensitive data cannot be stored on-chain, as all elements of both the EVM and any data stored on-chain is publicly readable.

All smart contracts have, in the end, only two functions - read and write. Reads don’t require gas (they’re essentially “free”), as they don’t cause any changes on-chain.

Solidity automatically provides some standard global variables: For example, the current block (block), the current transaction (tx), and the message attached to that transaction (msg).

The Solidity compiler produces deterministic builds (for a given version of the compiler).

Etherescan has an the ability to validate smart contract bytecode on-chain.

Remix IDE

When deploying a smart contract, choose “Environment > Injected Provider” to use MetaMask to sign and fund transactions.

When deploying a contract using the Remix IDE, do not fill out the “Value” field (leave it at 0)! Otherwise your transaction will fail.

To verify a contract on Etherscan, go to “Misc > Verify Contract”.

When creating a contract, the contract address can be seen in the “To” line of the creating transaction in Etherscan.

You should always verify your smart contract in Etherscan after upload in order to check that someone else hasn’t paid more gas to beat your transaction and deploy a modified version of your contract to the same address.

Once the smart contract is deployed, the Remix IDE will give you the ability to interact with its functions directly.


Ganache a “personal blockchain” - an Ethereum-compatible single-node blockchain that runs locally. It’s designed to make development easier by eliminating the entire gas transaction process. So generally you’d start by developing on Ganache, then move to the actual Ethereum TestNet, and then finally deploy on the MainNet.

Brownie layers a Python API and debugging tools onto Ganache.

dApps Top 10

[D01] Flash Loan - The ability to borrow money, use it, and return it all within a single block (i.e., the loan must be made and returned all within the same Solidity function call). If a smart contract allows for flash loans, an attacker can perform arbitrage attacks.

[D02] Insecure Design - Logical bugs. Keep your code as simple as possible, and only include functions relevant to the contract’s actual implementation. Use contract delegation to make the contract updatable.

[D03] Client-Side Code Injection - Regular old XSS, except on DeFi websites. So not really a blockchain vulnerability per se, but a common issue in web-based DeFi applications. This allows an attacker to submit arbitrary transactions to the user’s wallet (these still require user approval, though web3 apps tend to generate a lot of popups, so users tend to blindly approve these requests). In Checkpoint’s experience, this is currently the most common web3 vulnerability. (Note that many NFT platforms support SVG images, which can contain JavaScript, which is how people get hacked with NFT airdrops.) Content Security Policies (help) prevent this.

[D04] Reentrancy - A function makes an external call to an untrusted contract that can itself call the original function. It’s actually really easy to make this happen with Solidity, because the call() function is performed within the context of the calling user/contract. So all a malicious smart contract needs to do is redefine the call() function to be recursive (doing so via fallback() is sufficient). (I’m honestly not explaining this very well, as I’m not 100% sure I grok what’s going on here with execution context.) It’s important that every function that can be called externally be wrapped and balances always be zeroed out before funds are transferred.

[D05] Broken Access Control - This is a bug in delegated contracts. (Think of delegated contracts as contracts that have a variable contract address which all function call are pushed to. Updating the variable the points the delegated contract to a new contract.) The problem here is that the delegating contract and the contract being delegated to use the same slots in the EVM memory, so if the same variables aren’t defined in the same order in the contract being called, shenanigans can result. Variable names are just pointers to memory slots in Solidity.

[D06] Arithmetic Overflows - Buffer over- and under-flows for smart contracts. This is fixed in v8.0.0+ of Solidity.

[D07] Front Running - This is an attack where a miner makes a transaction with knowledge of a yet-to-be-committed transaction. This is possible because miners can choose which transactions they take, and to optimize their gains by picking transactions with higher gas fees. Basically, it’s a gas-enabled race condition. The way to prevent this is to split transactions into two, using the first transaction to set a flag that’s checked when actually performing the (valuable) second transaction.

[D08] Denial of Service - Some logical bugs can prevent smart contracts from dispersing the tokens they hold. Basically, the contract becomes a black hole that no tokens can ever leave. Use delegated contracts so that these sorts of logical bugs can be fixed.

[D09] Cryptographic Failure - These are the same kinds of cryptographic fails as we see in non-blockchain projects. Except now they’re on the blockchain too. Mostly, these involve people forgetting that there are no secrets on the blockchain.

[D10] Information Disclosure - Again, there are no secrets on the blockchain. Remember that persistent EVM variables must also be stored on-chain.


Checkpoint will be publishing a book about blockchain security this fall. It sounds like there may be a free version on GitHub as well.