探究Wallet Drainers使用Create2 Bypass钱包安全告警
字数 1068 2025-08-18 11:36:48
Wallet Drainers使用Create2绕过钱包安全告警技术分析
前言
随着链上总锁定价值(TVL)的不断增长,Wallet Drainers(钱包盗取者)活动日益频繁。本文深入分析攻击者如何利用Create2功能绕过钱包安全告警机制,实现隐蔽的资金窃取。
Create和Create2基础
Create操作
Create是Solidity中用于创建新合约的基本操作:
contract Factory {
event NewContract(address indexed createdContract);
function createNewContract() external {
address newContract = address(new MyContract());
emit NewContract(newContract);
}
}
contract MyContract {
address public owner;
constructor() {
owner = msg.sender;
}
}
特点:
- 新合约地址由创建者地址和nonce决定
- 无法预先计算合约地址
- 每次创建都会生成不同地址
Create2操作
Create2提供了更灵活的合约创建方式:
contract PredictableContract {
address public owner;
constructor(address _owner) payable {
owner = _owner;
}
}
contract Factory {
function deploy(uint _salt) public payable returns (address) {
bytes32 hash = keccak256(
abi.encodePacked(
bytes1(0xff),
address(this),
_salt,
type(PredictableContract).creationCode
)
);
address newContract = address(uint160(uint256(hash)));
return address(new PredictableContract{salt: bytes32(_salt)}(msg.sender));
}
}
关键特点:
- 使用salt值控制合约地址生成
- 可预先计算合约地址
- 相同salt值会生成相同地址
- 地址计算公式:
hash(0xff ++ factoryAddress ++ salt ++ bytecodeHash)
Create2地址预测方法
完整地址预测实现:
contract Factory {
function deploy(uint _salt) public payable returns (address) {
return address(new ContractDemo{salt: bytes32(_salt)}(msg.sender));
}
function getBytecode() public view returns (bytes memory) {
bytes memory bytecode = type(ContractDemo).creationCode;
return abi.encodePacked(bytecode, abi.encode(msg.sender));
}
function getAddress(uint256 _salt) public view returns (address) {
bytes32 hash = keccak256(
abi.encodePacked(
bytes1(0xff),
address(this),
_salt,
keccak256(getBytecode())
)
);
return address(uint160(uint256(hash)));
}
}
Wallet Drainers攻击流程
攻击者利用Create2绕过钱包安全告警的典型流程:
- 预先计算恶意合约地址:攻击者使用特定salt值计算出一个尚未部署的合约地址
- 诱导用户签名:让用户对看似无害的交易进行签名,实际上该交易会授权预先计算的地址操作资产
- 部署恶意合约:在用户签名后,攻击者使用预先计算的salt值部署实际恶意合约
- 转移资产:已部署的恶意合约执行实际资产转移操作
实际案例分析
以GMX代币被盗案例为例:
- 攻击者预先计算合约地址:
0xbD2BF58Be46619B7A22cE9457e1D51A10B82EB91 - 受害者签署
signalTransfer(address receiver)交易,授权该地址 - 攻击者部署预先计算的合约
- 合约执行以下恶意操作:
- 接受GMX代币转移
- 处理奖励
- 解除GMX和GLP的质押
- 将资产转移到攻击者控制地址
关键攻击合约代码片段:
function unstake(
address victim,
uint16 percentageForFirstAddressInBasisPoints,
address firstAddress,
address secondAddress,
uint256 lpPrice,
uint256 ethPrice
) public onlyOwner {
acceptTransfer(victim);
handleRewards();
unstakeGmx(percentageForFirstAddressInBasisPoints, firstAddress, secondAddress);
unstakeGlp(lpPrice, ethPrice);
// 转移资金...
}
防御建议
-
钱包安全增强:
- 对Create2相关交易增加特别警告
- 实现更严格的签名请求分析
- 对预先计算但未部署的地址进行标记
-
用户教育:
- 警惕任何要求签名"空投领取"或"奖励申领"的交易
- 仔细检查交易授权的合约地址
- 使用硬件钱包进行大额交易
-
合约开发实践:
- 实现多签授权机制
- 设置交易延迟执行
- 使用权限分级控制
总结
Create2功能虽然为智能合约开发带来了灵活性,但也被攻击者利用来绕过传统安全检测机制。了解这种攻击模式对于开发安全钱包应用和保护用户资产至关重要。随着攻击技术的演进,安全防护措施也需要不断更新以应对新的威胁。