题目地址 https://blockchain-ctf.securityinnovation.com
玩玩区块链练练手
前期准备:
关于remix ide的搭建方式,我只能说docker yyds
docker pull remixproject/remix-ide
docker run -p 80:80 remixproject/remix-ide
润起来就行了
0x1.Donation
签到题了算是,给的代码仍在ide里面,不过他的代码中import了一个safemath.sol,百度下载就行
safemath.sol
pragma solidity >=0.4.22 <0.6.0;
/**
* @title SafeMath
* @dev Unsigned math operations with safety checks that revert on error
*/
library SafeMath {
/**
* @dev Multiplies two unsigned integers, reverts on overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b);
return c;
}
/**
* @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
// Solidity only automatically asserts when dividing by 0
require(b > 0);
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend).
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a);
uint256 c = a - b;
return c;
}
/**
* @dev Adds two unsigned integers, reverts on overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a);
return c;
}
/**
* @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo),
* reverts when dividing by zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b != 0);
return a % b;
}
}
题目代码
pragma solidity 0.4.24;
import "../CtfFramework.sol";
import "../../node_modules/openzeppelin-solidity/contracts/math/SafeMath.sol";
contract Donation is CtfFramework{
using SafeMath for uint256;
uint256 public funds;
constructor(address _ctfLauncher, address _player) public payable
CtfFramework(_ctfLauncher, _player)
{
funds = funds.add(msg.value);
}
function() external payable ctf{
funds = funds.add(msg.value);
}
function withdrawDonationsFromTheSuckersWhoFellForIt() external ctf{
msg.sender.transfer(funds);
funds = 0;
}
}
直接跑起来调用withdrawDonationsFromTheSuckersWhoFellForIt,填入自己的合约地址就可以了。
0x2.Lock Box
pragma solidity 0.4.24;
import "../CtfFramework.sol";
contract Lockbox1 is CtfFramework{
uint256 private pin;
constructor(address _ctfLauncher, address _player) public payable
CtfFramework(_ctfLauncher, _player)
{
pin = now%10000;
}
function unlock(uint256 _pin) external ctf{
require(pin == _pin, "Incorrect PIN");
msg.sender.transfer(address(this).balance);
}
}
now的意思是获取当前时间戳,然后unlock这里还需要获取pin值,pin作为private的变量,无法被外部call,所以可以使用getStorageAt来获取值,这里pin的话是因为framework它有个mapping占了一位,所以是1
代码:web3.eth.getStorageAt(‘题目地址’, 1, console.log);
0x3 Piggy bank
代码:
pragma solidity 0.4.24;
import "../CtfFramework.sol";
import "..//SafeMath.sol";
contract PiggyBank is CtfFramework{
using SafeMath for uint256;
uint256 public piggyBalance;
string public name;
address public owner;
constructor(address _ctfLauncher, address _player, string _name) public payable
CtfFramework(_ctfLauncher, _player)
{
name=_name;
owner=msg.sender;
piggyBalance=piggyBalance.add(msg.value);
}
function() external payable ctf{
piggyBalance=piggyBalance.add(msg.value);
}
modifier onlyOwner(){
require(msg.sender == owner, "Unauthorized: Not Owner");
_;
}
function withdraw(uint256 amount) internal{
piggyBalance = piggyBalance.sub(amount);
msg.sender.transfer(amount);
}
function collectFunds(uint256 amount) public onlyOwner ctf{
require(amount<=piggyBalance, "Insufficient Funds in Contract");
withdraw(amount);
}
}
contract CharliesPiggyBank is PiggyBank{
uint256 public withdrawlCount;
constructor(address _ctfLauncher, address _player) public payable
PiggyBank(_ctfLauncher, _player, "Charlie")
{
withdrawlCount = 0;
}
function collectFunds(uint256 amount) public ctf{
require(amount<=piggyBalance, "Insufficient Funds in Contract");
withdrawlCount = withdrawlCount.add(1);
withdraw(amount);
}
}
参考文章:https://www.anquanke.com/post/id/168037
漏洞点是spolidity的继承,进行分析,在charliesPiggybank与piggybank中都有collectfunds函数,但是
piggybank中只有owner能调用,而前者是继承自piggy板块,那么就把自己的collectfunds的函数覆盖了piggybank中的函数,所以只需要调用合约中的collectfund函数即可解决
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
暂无评论内容