In this challenge, you are provided with a contract that has no verified source code.
The contract is deployed using raw bytecode. By analyzing the bytecode and the deployment script, we can deduce:
const challenge9BytecodeBase = "...";
const nftFlagsAddress = await nftFlags.getAddress();
const challenge9Bytecode = challenge9BytecodeBase + nftFlagsAddress.slice(2).padStart(64, "0");
const deployerSigner = await hre.ethers.getSigner(deployer);
const nonce = await deployerSigner.getNonce();
const feeData = await hre.ethers.provider.getFeeData();
const rawTx = {
nonce: nonce,
maxFeePerGas: feeData.maxFeePerGas,
maxPriorityFeePerGas: feeData.maxPriorityFeePerGas,
gasLimit: 800_000,
to: null,
value: 0,
data: challenge9Bytecode,
chainId: (await hre.ethers.provider.getNetwork()).chainId,
};
const txResponse = await deployerSigner.sendTransaction(rawTx);
const txReceipt = await txResponse.wait();
const challenge9Address = txReceipt?.contractAddress;
if (challenge9Address) await save("Challenge9", { address: challenge9Address, abi: [] });
console.log("🚩 Challenge #9 deployed at:", challenge9Address);
What do you notice? Who is deploying this contract?
PUSH18 0x424720435446204368616c6c656e67652039. I wonder what this might do?
0x23cfec7e. Take a look at what it does - you can try using https://ethervm.io/decompile.
(bool success, ) = challenge9.call(
abi.encodeWithSelector(0x23cfec7e, signerAddress, signature)
);
Why this works:
- The contract relies on a specific "trusted" signer to authorize mints.
- However, the "trusted" signer's key was generated from a public, insecure mnemonic committed in the deployment script.
Hardcoded Secrets & Test Mnemonics:
Never use default mnemonics or commit .env files containing real private keys to version control. If a deployment script containing a mnemonic (or pointing to a public one) is pushed to GitHub, any address derived from it is compromised immediately.
Security Through Obscurity: Security through obscurity refers to the idea of making something secure by not revealing the implementation (in this case, the contract). However, any contract can be reverse engineered given enough of an incentive.
This is a variation of S1C4: Who Can Sign This?, but obscured by the lack of source code and the indirect way the key was leaked, similar to S1C8: The unverified.