Tags: web3py
Rating:
These are the challenge contracts
```
# Setup.sol
pragma solidity ^0.8.18;
import {ShootingArea} from "./ShootingArea.sol";
contract Setup {
ShootingArea public immutable TARGET;
constructor() {
TARGET = new ShootingArea();
}
function isSolved() public view returns (bool) {
return TARGET.firstShot() && TARGET.secondShot() && TARGET.thirdShot();
}
}
```
```
# ShootingArea.sol
pragma solidity ^0.8.18;
contract ShootingArea {
bool public firstShot;
bool public secondShot;
bool public thirdShot;
modifier firstTarget() {
require(!firstShot && !secondShot && !thirdShot);
_;
}
modifier secondTarget() {
require(firstShot && !secondShot && !thirdShot);
_;
}
modifier thirdTarget() {
require(firstShot && secondShot && !thirdShot);
_;
}
receive() external payable secondTarget {
secondShot = true;
}
fallback() external payable firstTarget {
firstShot = true;
}
function third() public thirdTarget {
thirdShot = true;
}
}
```
The modifiers basically put the function at the "\_;". In this case the contract forces you to call `fallback`, `receive` and `third` in order. However, `fallback` and `receive` are special functions, as documented [here](https://docs.soliditylang.org/en/v0.8.19/contracts.html#special-functions).
The `fallback` function is called when the contract receives a call for a function it does not know and the `receive` function is called when the contract receives money without a function call. To trigger fallback I added the following function to my local ShootingArea code.
```
function invalid(uint x) public {
thirdShot = true;
}
```
Then I used the following script to communicate to the blockchain:
```python
from web3 import Web3
from solcx import compile_files
addr = "0xf5Eb625F3BCfc73021cCC0cadf935EB22Cbe80d4"
target = "0x3ac666e2c809Ba6d471ad501925de80d23566599"
compiled = compile_files(["ShootingArea.sol"], output_values=["abi"], solc_version="0.8.18")
abi = compiled['ShootingArea.sol:ShootingArea']['abi']
w3 = Web3(Web3.HTTPProvider('http://68.183.37.122:31550'))
print("current balance", w3.eth.get_balance(addr), "wei")
contract = w3.eth.contract(address=target, abi=abi)
# invalid function added to source with an uint parameter
# first target calls fallback (special function)
contract.functions.invalid(10).transact()
# second target calls receive (special function)
w3.eth.send_transaction({"from":addr, "to":target,"value":1,})
# third target calls third
contract.functions.third().transact()
```
The flag is `HTB{f33l5_n1c3_h1771n6_y0ur_74r6375}`