Gotta Go Fast
I won't have have to worry about running out of entropy, I'm going to have my OTP generated forever with this new script!
Connect at nc socket.cryptohack.org 13372
problem.py
import time
from Crypto.Util.number import long_to_bytes
import hashlib
from utils import listener
FLAG = b'crypto{????????????????????}'
def generate_key():
current_time = int(time.time())
key = long_to_bytes(current_time)
return hashlib.sha256(key).digest()
def encrypt(b):
key = generate_key()
assert len(b) <= len(key), "Data package too large to encrypt"
ciphertext = b''
for i in range(len(b)):
ciphertext += bytes([b[i] ^ key[i]])
return ciphertext.hex()
class Challenge():
def __init__(self):
self.before_input = "Gotta go fast!\n"
def challenge(self, your_input):
if not 'option' in your_input:
return {"error": "You must send an option to this server"}
elif your_input['option'] == 'get_flag':
return {"encrypted_flag": encrypt(FLAG)}
elif your_input['option'] == 'encrypt_data':
input_data = bytes.fromhex(your_input['input_data'])
return {"encrypted_data": encrypt(input_data)}
else:
return {"error": "Invalid option"}
"""
When you connect, the 'challenge' function will be called on your JSON
input.
"""
listener.start_server(port=13372)
Solution
As we can see current time is being used for generating the key.So while sending request we can store current time and get encrypted_flag and then decrypt it back to the flag.
import time
from Cryptodome.Util.number import long_to_bytes
import hashlib
from pwn import *
import json
def generate_key():
current_time = int(time.time())
key = long_to_bytes(current_time)
return hashlib.sha256(key).digest()
def encrypt(b):
key = generate_key()
assert len(b) <= len(key), "Data package too large to encrypt"
ciphertext = b''
for i in range(len(b)):
ciphertext += bytes([b[i] ^ key[i]])
return ciphertext
# connect to socket.cryptohack.org 13372
r = remote('socket.cryptohack.org', 13372)
r.recvuntil('Gotta go fast!\n')
key = generate_key()
r.sendline('{"option": "get_flag"}')
flag = json.loads(r.recvline().decode())['encrypted_flag']
flag = encrypt(bytes.fromhex(flag))
print(flag)
Flag after running the program is crypto{t00_f4st_t00_furi0u5}