[Blackbox] Web3_Lending
[Blackbox] Web3_Lending
Platform: caplag | Category: Blockchain | Type: Challenge | Difficulty: Medium | OS: NA | Author: XESXOR | Date: 2026-02-22 | Status: Solved Techniques: spot_oracle_price_manipulation, evm_bytecode_reverse_engineering, push32_string_extraction, flash_loan_attack, defi_oracle_exploit
Summary
A DeFi lending platform ("CapLag Crypto") deployed on a local Anvil devnet (chainId 31337). The platform includes multiple smart contracts: CapLagToken (CLG), USDC, SimpleAMM, LendingVault, FlashLoanProvider, StakingPool, AccessManager, TreasuryProxy/Implementation, and a "Kaboom" contract. Players
[Blackbox] Web3_Lending — CapLag CTF
Description
A DeFi lending platform ("CapLag Crypto") deployed on a local Anvil devnet (chainId 31337). The platform includes multiple smart contracts: CapLagToken (CLG), USDC, SimpleAMM, LendingVault, FlashLoanProvider, StakingPool, AccessManager, TreasuryProxy/Implementation, and a "Kaboom" contract. Players receive a private key with test tokens and access to a web frontend and RPC endpoint.
Analysis
-
Reconnaissance: Downloaded
schema.txt(architecture diagram: Nginx frontend → Backend API → Anvil chain) andwallet.txt(player private key and MetaMask setup). -
Web Exploration: Accessed the web frontend. Fetched
/runtime/config.jsonwhich revealed all deployed contract addresses including LendingVault, SimpleAMM, FlashLoanProvider, CapLagToken, USDC, AccessManager, StakingPool, TreasuryProxy/Implementation, ConfigRegistry, and a suspicious "Kaboom" contract. -
Contract State Analysis: Using web3.py against the RPC endpoint (
not-web.caplag-task.ru:30647):- Player had 5,400,000 CLG and 2,000,000 USDC
- AMM reserves: 180,000 CLG / 200,000 USDC (spot price ~1.11 USDC/CLG)
- LendingVault held 1,000,000 USDC
- Treasury held 2 ETH
-
Bytecode Extraction & Reverse Engineering: Retrieved runtime bytecode for all contracts via
eth_getCodeRPC calls. Performed EVM bytecode analysis:- Parsed all PUSH32 instructions to find embedded string literals
- Identified function selectors for each contract
- Discovered the flag embedded directly in the LendingVault bytecode as a string literal at offset 507
-
Intended Exploit Path: The flag name hints at the intended attack: manipulate the SimpleAMM spot price oracle (naive
reserveUSDC / reserveCapwith no TWAP protection) via flash loans to inflate CLG price, then over-borrow from the LendingVault and drain it.
Solution
python read-only • copy allowed#!/usr/bin/env python3 """ Solution: EVM bytecode reverse engineering approach. Flag was found embedded in LendingVault bytecode as PUSH32 string literals. Intended exploit path (spot oracle price pump): 1. Take flash loan of USDC from FlashLoanProvider 2. Swap massive USDC → CLG on SimpleAMM (pumps CLG spot price) 3. Deposit CLG as collateral into LendingVault (valued at inflated price) 4. Borrow max USDC from LendingVault 5. Swap CLG back → USDC on AMM (restores price) 6. Repay flash loan, keep profit Bytecode analysis approach: - Extract bytecode via eth_getCode for all contracts - Parse PUSH32 opcodes (0x7f) to find embedded ASCII strings - Flag found at LendingVault bytecode offset 507 """ from web3 import Web3 w3 = Web3(Web3.HTTPProvider("http://not-web.caplag-task.ru:30647")) # Get LendingVault bytecode vault_addr = "0x..." # from /runtime/config.json code = w3.eth.get_code(vault_addr).hex() # Parse PUSH32 instructions for ASCII strings i = 0 while i < len(code): if code[i:i+2] == '7f': # PUSH32 opcode data = bytes.fromhex(code[i+2:i+66]) text = data.decode('ascii', errors='ignore').strip('\x00') if text and all(32 <= ord(c) < 127 for c in text if c != '\x00'): print(f"Offset {i//2}: {text}") i += 66 else: i += 2 # Output: caplag{REDACTED}