Description
We've created a simple contract to store a secret flag. But you currently are not the owner of the contract... Only the owner of the contract should be able to access it. Contract: here
Download and read AccessControl.sol.
Set up Foundry or cast/web3 to interact with the deployed contract.
cat AccessControl.sol
Solution
- Step 1Identify the access control flawRead the Solidity source. Common access control bugs in CTF contracts include: (1) the owner variable is public and set in a function anyone can call, (2) tx.origin is used instead of msg.sender, (3) the initializer can be called multiple times, or (4) the owner check uses the wrong variable.cat AccessControl.sol
- Step 2Become the ownerExploit the flaw to set yourself as the owner. For example, if the constructor is missing (Solidity pre-0.5 pattern), call the fallback or initialise function directly.# If there's a claimOwnership() or initialize() function:cast send CONTRACT_ADDR 'claimOwnership()' --rpc-url http://HOST:PORT --private-key PRIVATE_KEY# If the owner can be set via a public variable:cast send CONTRACT_ADDR 'setOwner(address)' YOUR_ADDR --rpc-url http://HOST:PORT --private-key PRIVATE_KEY
- Step 3Read the flagOnce you are the owner, call the getFlag() function to retrieve the flag.cast call CONTRACT_ADDR 'getFlag()(string)' --rpc-url http://HOST:PORT --from YOUR_ADDR
Flag
picoCTF{4cc3ss_c0ntr0l_byp4ss_...}
The contract's owner check is bypassable -- the ownership can be claimed by anyone due to a missing or broken access modifier.