Appearance
S1C3: Empty Contract?
1. 问题
合约在 etherscan 上显示为"空"(无已验证源码),但实际上有逻辑。需要调用 mintFlag() 获取 NFT。
2. 原因
合约的 mintFlag() 函数实际上在构造函数中会自动调用。挑战的核心是理解:合约在部署时就完成了目标,攻击者需要部署一个同样的合约(在构造函数中攻击)。
3. 方案
部署一个攻击合约,在构造函数中设置目标合约需要的状态,然后调用目标合约的攻击函数:
solidity
contract S1C3Solution {
constructor(address challenge) {
// Setup logic here
IChallenge(challenge).mintFlag();
}
}
4. 遇到的陷阱
构造函数攻击时机: mintFlag 的检查逻辑在构造函数中与部署后的执行环境不同。
5. 陷阱的原因
合约存储状态在构造函数执行期间和之后是不同的 — 某些状态变量(如 block.timestamp)在构造期间可以预测。
6. 如何解决
使用 Foundry 脚本部署攻击合约,在构造函数中完成所有逻辑。
7. 技术要点
| 要点 | 说明 |
|---|---|
| 构造函数攻击 | Solidity 合约的构造函数在部署时自动执行,可以用来做一次性攻击 |
| 已部署 vs 构造函数 | 合约在构造函数中可以通过特定检查,而在部署后不行(如依赖 EXTCODESIZE 为零) |