Skip to content

Instantly share code, notes, and snippets.

@dwendt
Created September 16, 2019 22:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dwendt/10fe5e7f6a537df72f2811c30ed268c0 to your computer and use it in GitHub Desktop.
Save dwendt/10fe5e7f6a537df72f2811c30ed268c0 to your computer and use it in GitHub Desktop.
bank.py rwctf 2019
from pwn import *
import IPython
import sha
import sys
import itertools
import string
from base64 import b64encode
from base64 import b64decode
from schnorr import *
r = remote('tcp.realworldctf.com',20014)
# Get SHA1
def getSHA(data):
ha = hashlib.sha1()
ha.update(data)
return ha.digest()
# Do proof of work
def findSHA(challenge):
charset = "".join(chr(i) for i in range(0x00, 0x100))
for p in itertools.chain.from_iterable((''.join(l) for l in itertools.product(charset, repeat=i)) for i in range(5, 5 + 1)):
candidate = challenge + p
proof = getSHA(candidate)
if((ord(proof[-2]) == 0) and (ord(proof[-1]) == 0)):
return candidate
return None
pow_msg = r.recvline()
powre = re.compile("length (.+) bytes, starting with (.+)\n")
powlen, powprefix = powre.search(pow_msg).groups()
print("[+] calculating pow len: {} prefix: {}".format(powlen,powprefix))
powresult = findSHA(powprefix)#dopow(powprefix, int(powlen))
print("[!] result: {}".format(powresult))
r.send(powresult) # don't b64encode this
print(r.recvline()) # "generating keys"
print(r.recvuntil(':')) # "send us pub key"
# send a deposit with a regular mypub
(reg_priv, reg_pub) = generate_keys()
keysend = "{},{}".format(reg_pub[0],reg_pub[1])
r.sendline(b64encode(str(keysend)))
print("[+] sent reg_pubkey, going to deposit")
#print(r.recvregex(re.compile("priority!")))
print(r.recv(timeout=0.5))
print("[+] sent deposit")
r.sendline(b64encode("1"))
print(r.recvuntil('e')) # "Please send us your signature"
signed_deposit = schnorr_sign('DEPOSIT', reg_priv)
r.sendline(b64encode(signed_deposit))
print("[+] sent deposit request!")
print(r.recvline()) # "Coin deposited.\n")
###########################
## grabbing pk
print(r.recvuntil(':')) # "send us pub key"
#print(r.recvline()) # Please send us your public key
keysend = "{},{}".format(reg_pub[0],reg_pub[1])
r.sendline(b64encode(str(keysend)))
print("[+] sent reg_pubkey, going to grab their PK")
print(r.recvuntil("priority!\n"))
r.sendline(b64encode("3"))
re_theirpk = re.compile("as one of us: (.+)\n")
theirpk_str = r.recvregex(re_theirpk)
print(theirpk_str)
theirpk_result = re_theirpk.search(theirpk_str).groups()[0]
print("[+] got their public key: {}".format(theirpk_result))
re_pkvals = re.compile("\((.+)L, (.+)L\)")
tpk1, tpk2 = re_pkvals.search(theirpk_result).groups()
server_pub = (int(tpk1), int(tpk2))
##########################
## send a withdraw with a malicious mypub
p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
G = (0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798, 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8)
server_pub_2 = (server_pub[0], (server_pub[1]*-1) % p)
malicious_point = point_add(reg_pub, server_pub_2)
print(r.recvuntil(':')) # "send us pub key"
keysend = "{},{}".format(malicious_point[0],malicious_point[1])
r.sendline(b64encode(str(keysend)))
print("[+] sent malicious_pk, going withdraw")
print(r.recvuntil("priority!\n"))
r.sendline(b64encode("2"))
# sent malicious pk, send the sig now
my_signed_withdraw = schnorr_sign('WITHDRAW', reg_priv)
r.sendline(b64encode(str(my_signed_withdraw)))
print(r.recvall(timeout=4))
IPython.embed()
print(r.recvline())
print(r.recvline())
print(r.recvline())
print(r.recvline())
IPython.embed()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment