Smart Contracts
A few small bits about attacking Smart Contracts in Web3
Compiling .sol to .abi
A contract's source code is found in .sol
files, but code often requires a general structure instead, which is the Application Binary Interface (ABI) format, simply encoded in JSON. You can compile Solidity code into .abi
files that you can use in your attacking script to interact with the contract in a known way.
You can compile a single file to ABI into the current directory using the following command:
It might complain about having the wrong compiler version installed, but this can often be circumvented by changing the version in the contract source itself. You might get a ParserError
like this:
It says the current version is 0.7.3
, so simply change that first line in the source:
Simple Interaction
Take the following contract as a simple example:
To interact with a smart contract on a private chain, you need the following:
Then you can use libraries like web3.py or web3.js to do the heavy lifting. The libraries are very similar in usage, but in the following examples, I will use the Python version.
It starts with connecting to the RPC provider, and creating an account object from your private key:
From here, you likely want to interact with a contract. You can get an instance of the contract in Python by opening the .abi
file (see Compiling .sol to .abi) and providing the address of the contract on the server.
Now that we have an instance of the contract, we can interact with it by calling functions on it. In the example Solidity code above, we need to call the call_me()
function with an argument of 42
. In our script that would look like this:
If you run this script and the tx_hash
prints something, it probably worked. Otherwise, you will likely receive a clear Exception on why it did not work.
Manual Transactions
These function calls abstract away a lot of details, but sometimes we as the attacker want more low-level control over the transaction being sent. Here are two examples.
The fallback()
method
fallback()
methodThe contract might contain a payable method named fallback()
:
You cannot call this function directly, because it has a special meaning. This function is called when the function you try to call does not exist. It is often used for updated contracts that need to handle the case when scripts interacting with it don't update. But to intentionally call this function we would need to try and call a wrong function name in our script.
Web3 won't actually let you do this straight away, to help you not make mistakes. But in the case where you intentionally want to do this, you can trick it into thinking the wrong method does exist.
To bypass this, we can just manually change the .abi
file to add a function called wrong
, and make it think it exists:
When we now run the script again, it will correctly pass it through to the fallback()
method.
The receive()
method
receive()
methodYour contract may also have receive()
method:
This method is used when you aren't calling a function at all, so when there is no data involved in your transaction, specifically a transaction directly to the contract address. To trigger this function we just have to manually create a transaction and send it over, without the data:
component. Here is an example:
In this case, we send 0 ether with some gas price configuration. It is sent to
the contract address which will trigger the receive()
method.
As I hinted, you can add a data
component to this transaction
which calling functions will automatically do for you. Here you can manually craft any call you want to make.
Requirements
With more involved contracts, you'll likely find the modifier
keyword and the require()
function. These can set specific conditions for if you can call a method or not. If this condition fails, your call will not go through. For example:
Here, someone would first have to call open_gates()
before they could call enter()
. Keep in mind that this state is remembered, so if you set allowed = true
it will now forever be true, and you will be allowed in the next call.
Last updated