keyboard_arrow_up

title: Writeup BreizhCTF 2022 - Chauffe-haut
date: Apr 14, 2022
tags: BreizhCTF writeups web3 smart-contracts


Writeup BreizhCTF 2022 - Chauffe-haut

Description:

# Chauffe-haut

    Value: 433

    Description:

    Des cryptocriminels ont décidé d'organiser leurs opérations à l'aide du réseau breton.

Les Kreizh Ker Leon Foll (KKLF) doivent être arretés.

Pour commencer, récupérez l'adresse du chef du KKLF depuis ce contrat !

Les challenges web3 se passent ici : http://10.50.254.254:22000/

Auteur: iHuggsy

Format : BZHCTF{}

Introduction

First of all, let's take a look at the Solidity smart contract source code:

pragma solidity 0.8.13;

// @dev : iHuggsy
contract KKLF_v1
{
    address public chef;

    constructor ()
    {
        chef = msg.sender;
    }

}

It is specified that the blockchain provider that we need to connect to is http://10.50.254.254:22001, and we are going to use the web3py library to flag this smart contract.

Let's import the library and connect to the custom provider:

from web3 import Web3, IPCProvider
from web3.middleware import geth_poa_middleware

w3 = Web3(Web3.HTTPProvider('http://10.50.254.254:22001'))

We need to setup a Geth-style Proof of Authority for the challenge to work:

w3.middleware_onion.inject(geth_poa_middleware, layer=0)

We then need an address to interact with the contract, And there is a function for this: w3.geth.personal.new_account():

w3.geth.personal.new_account('supersuperpassphrase')

Now, the last thing we need to do is to bind to the contract. We will need the ABI of the contract which is like the structure of the contract that define the different attributes and methods that are present in it. We can use some websites like remix.ethereum.org or compile it with compile_source().

Our ABI is:

abi = [
    {
        "inputs": [],
        "stateMutability": "nonpayable",
        "type": "constructor"
    },
    {
        "inputs": [],
        "name": "chef",
        "outputs": [
            {
                "internalType": "address",
                "name": "",
                "type": "address"
            }
        ],
        "stateMutability": "view",
        "type": "function"
    }
]

Once we have the contract adress and the ABI, we can bind to it!

deployed_contract = w3.eth.contract(address="0x5D86a6e8F1524DbC23f62653CBF17db057a2cB0e", abi=abi)

The only thing left is to get the chef attribute content:

print(deployed_contract.functions.chef().address)

And thus we get the flag!

Flag: BZHCTF{0x95c30ADDae9E59AB756f7E31A33203651b4B7374}

Thanks for reading all the way down there!

Complete final code: chalweb3_1.py

from web3 import Web3, IPCProvider
from web3.middleware import geth_poa_middleware

w3 = Web3(Web3.HTTPProvider('http://10.50.254.254:22001'))
w3.middleware_onion.inject(geth_poa_middleware, layer=0)

#print(w3.clientVersion)
#print(w3.eth.get_block('latest'))
#print(w3.isConnected())

abi = [
    {
        "inputs": [],
        "stateMutability": "nonpayable",
        "type": "constructor"
    },
    {
        "inputs": [],
        "name": "chef",
        "outputs": [
            {
                "internalType": "address",
                "name": "",
                "type": "address"
            }
        ],
        "stateMutability": "view",
        "type": "function"
    }
]

print(w3.geth.personal.new_account('supersuperpassphrase'))

deployed_contract = w3.eth.contract(address="0x5D86a6e8F1524DbC23f62653CBF17db057a2cB0e", abi=abi)

print(deployed_contract.functions.chef().address)