From d3f434e36f17ad8ac773149ae48170ee8ae13f2e Mon Sep 17 00:00:00 2001 From: six <51x@keemail.me> Date: Wed, 17 Aug 2022 10:13:02 +0200 Subject: [PATCH] EthKeyGen --- cctf_challenge.py | 48 ++++++++++++++++++++++++++++++ ethkeygen.py | 75 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 cctf_challenge.py create mode 100644 ethkeygen.py diff --git a/cctf_challenge.py b/cctf_challenge.py new file mode 100644 index 0000000..ee0f92f --- /dev/null +++ b/cctf_challenge.py @@ -0,0 +1,48 @@ +#!/usr/bin/python3 + +# Author: six +# Made for: CCTF during BsidesBUD 2022 + +# require(owner() == ecrecover(keccak256(abi.encodePacked(this, tokenId)), v, r, s), "Should be signed correctly"); +# https://privatekeys.pw/keys/ethereum/1 + +from web3.auto import w3 +from eth_account.messages import encode_defunct +from flask import Flask, request + +from base64 import b64encode + +app = Flask(__name__) + +txt = b'''Lets play a game... what is the private key if: + +SignedMessage(messageHash=HexBytes('0xd65fc3b188dd92cfcb2a193a50840c1b782030fb06c5eee3125dadc48b9042ee'), r=93061353422229139783272046072373682100846510432479107335894930000050943813187, s=18897300799783892124841480819482900155126442998358954848148962214377508383077, v=28, signature=HexBytes('0xcdbedc050cdf4e1a236535365e1563312905fc47aa8238a8ab06decfbb31e64329c77e43945949494800d0c432d037867ea10aad935abf98c63ae2befaf929651c')) + +If you send the correct private key as argument to /verify?p= in HEX format (without 0x), then you will get the CCTF flag which lets you in to the next yacht event + swag at BsidesBUD. +''' +b64=b64encode(txt) + +@app.route('/') +def hello(): + return b64 + +@app.route('/verify', methods=['GET']) +def search(): + args = request.args + args.get("v", default="", type=str) + print(args) + + msg = "1" + private_key = "0000000000000000000000000000000000000000000000000000000000000006" # <- hex | pub -> 0xE57bFE9F44b819898F47BF37E5AF72a0783e1141 + message = encode_defunct(text=msg) + signed_message = w3.eth.account.sign_message(message, private_key=private_key) + print(signed_message) + p = args.get('p') + if p == None: + return "Please specify ?p" + if p == private_key: + return "CCTF{w3lc0m3_t0_th3_y4xx} --> take this flag to six or ra33it0 at BsidesBUD 2022 and he will announce you as the winner if you are the fastest. If you are not there physically, use Matrix, but then you will miss the swag!" + return "Wrong key." + +if __name__ == '__main__': + app.run(debug=False) diff --git a/ethkeygen.py b/ethkeygen.py new file mode 100644 index 0000000..4dca713 --- /dev/null +++ b/ethkeygen.py @@ -0,0 +1,75 @@ +#!/usr/bin/python3 +# Eth ECDSA key generator for web3 hacking +# Author: six + +# require(owner() == ecrecover(keccak256(abi.encodePacked(this, tokenId)), v, r, s), "Should be signed correctly"); +# https://privatekeys.pw/keys/ethereum/1 + +from web3.auto import w3 +from eth_account.messages import encode_defunct + +#def sign_mint(): +msg = "0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf" +msg = "1" +msg = "1659023558XXX" # unix time +private_key = "0000000000000000000000000000000000000000000000000000000000000001" # <- hex | pub -> 0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf +message = encode_defunct(text=msg) +signed_message = w3.eth.account.sign_message(message, private_key=private_key) + +print("Public key: 0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf") +print("Private key: 0000000000000000000000000000000000000000000000000000000000000001") + +print(msg) + +print("Signed message: ") +#print(type(signed_message)) +print(signed_message) + +print("\n Recovered message: ") +print(w3.eth.account.recover_message(message, signature=signed_message.signature)) + +#sign_mint() + + +from web3 import Web3 + +# ecrecover in Solidity expects v as a native uint8, but r and s as left-padded bytes32 +# Remix / web3.js expect r and s to be encoded to hex +# This convenience method will do the pad & hex for us: +def to_32byte_hex(val): + return Web3.toHex(Web3.toBytes(val).rjust(32, b'\0')) + +ec_recover_args = (msghash, v, r, s) = ( + Web3.toHex(signed_message.messageHash), + signed_message.v, + to_32byte_hex(signed_message.r), + to_32byte_hex(signed_message.s),) + +print("\n Recovered args (msghash, v, r, s):") +print(ec_recover_args) + +# https://privatekeys.pw/keys/ethereum/1 + +# https://web3py.readthedocs.io/en/stable/web3.eth.account.html?highlight=sign#sign-a-message +# w3.eth.account.recover_message(message, signature=signed_message.signature) +#'0x5ce9454909639D2D17A3F753ce7d93fa0b9aB12E' + + +from flask import Flask, request + +app = Flask(__name__) + +@app.route('/') +def hello(): + return 'Lets play a game... move to /verify and ? is the private key if: ' + +@app.route('/verify', methods=['GET']) +def search(): + args = request.args + args.get("v", default="", type=str) + print(args) + #0000000000000000000000000000000000000000000000000000000000000001 + return args + +#if __name__ == '__main__': +# app.run(debug=False)