pragma solidity ^0.7.0;
contract Bank {
uint48 flag_cost = 50;
uint48 amount_you_have = 0;
uint48 loaned = 0;
function deposit(uint48 amount) public payable {
require(msg.sender==YOUR_WALLET_ADDRESS,"Please use the wallet provided to you"); // This is for security purposes
require(amount==msg.value,"Please send exact amount");
amount_you_have += amount;
}
function withdraw(uint48 amount) public payable {
require(msg.sender==YOUR_WALLET_ADDRESS,"Please use the wallet provided to you"); // This is for security purposes
require((amount) < amount_you_have, "You cannot withdraw what you do not have!");
amount_you_have -= amount;
msg.sender.call{value:amount}("");
}
function getMoney() public payable {
// Used for deployment, can be safely ignored
}
function loan(uint48 amount) public payable {
require(msg.sender==YOUR_WALLET_ADDRESS,"Please use the wallet provided to you"); // This is for security purposes
loaned += amount;
msg.sender.call{value:amount}("");
}
function isChallSolved() public view returns (bool solved) {
if ((amount_you_have >= flag_cost) && (loaned == 0)) {
return true;
}
else {
return false;
}
}
}
Solution:
The goal of this challenge is to make the function isChallSolved() return true. Once achieved, the challenge will be completed. The function will check whether the balance of amount_you_have is greater than flag_cost and if the loan is zero.
In this instance, they have provided the following details:
┌── 👽AKUMA 🥷 ➤➤ 🌐10.10.0.12
├──[ ~/Desktop/CTF/imaginary2024]
└─ ⚔ nc 34.30.117.150 40001
[1] Get an instance
[2] Get the flag
Choice: 1
contract address: 0x1969eF364FeFBeBa4E3509aF4D7B8b62E64fcEc4
rpc-url: http://34.30.117.150:49140
Wallet private-key: 0x1c8a5f5de62440776604396f557ebc76e3b23dfbe317b638a4b5b205eeb5c055
Wallet address: 0x6045a94A76888C0f6DC6Bc379FE8a41de4f44A64
Secret: a1fbb572080841e8b3f04d7a756b5c7727432c633094cd44f81bbb1ff283a997
Please save the provided secret, it will be needed to get the flag
First, I checked the balance of the provided wallet and contract. If the wallet has sufficient funds to deposit 50 wei into the contract, the challenge will be solved upon deposit. Here is the script to check the balance:
After running the above code, I obtained my balance as follows:
┌── 👽AKUMA 🥷 ➤➤ 🌐10.10.0.12
├──[ ~/Desktop/CTF/imaginary2024]
└─ ⚔ node 1_accounts.js
ETH Balance of contract --> 0.000117883415867467 ETH
ETH Balance of wallet --> 0.000244134809434108 ETH
We can see that the ETH balance of the wallet is much greater than 50 wei, which is also sufficient to cover the gas fee for calling the deposit() function. Once we call the deposit() function, the challenge will be solved.
Here is the script for calling the deposit() function:
const { ethers } = require("ethers");
const provider = new ethers.providers.JsonRpcProvider(`http://34.30.117.150:41378`)
const privateKey="0xd6d9b94c56b738647ce6119556117f54510e2a46135fc19dfc60613fc16b8246"
const wallet = new ethers.Wallet(privateKey, provider)
const ABI = [
"function loan(uint48 amount) public payable",
"function deposit(uint48 amount) public payable",
"function isChallSolved() public view returns (bool solved)",
];
const address = '0xB46fe37aE41576a6D7215cC9c0e7c78986fA8BBC';
const contract = new ethers.Contract(address, ABI, provider)
const contractWithWallet = contract.connect(wallet);
const deposit=async()=>{
const tx=await contractWithWallet.deposit(50,{value: 50});
await tx.wait()
console.log(tx)
}
deposit()
Flag:
┌── 👽AKUMA 🥷 ➤➤ 🌐10.10.0.12
├──[ ~/Desktop/CTF/imaginary2024]
└─ ⚔ nc 34.30.117.150 40000
[1] Get an instance
[2] Get the flag
Choice: 2
Please enter the hash provided during deployment: 18e21d8ae3d0145a4f0cfdb824a408d15ee500198532d986f4593dc92f3f52f7
Flag: ictf{1_h4t3_uns1gn3d_1nt5_7f4d3a1b}