from Cryptodome.Cipher import AESfrom Cryptodome.Util.Padding import pad, unpadimport osimport hashlibimport itertoolsimport stringdef stronghash(msg: bytes) -> bytes: hashed_msg = pad(msg, 16) for _ in "Stronger!!": hashed_msg = AES.new(hashed_msg[:16], AES.MODE_ECB).encrypt(hashed_msg) for length in range(2, 16): md5 = hashlib.md5(hashed_msg[:length]) hashed_msg = md5.digest() for length in range(16, 32): sha256 = hashlib.sha256(hashed_msg[:length]) hashed_msg = sha256.digest() return hashed_msg
요 stronghash 이 친군데.. 사실 아래 하나만 더 보자
PY</>
def main(): print("I invented my custom hash function, which is very very strong") print("Can you steal my flag from it?") stage = 100 pw = [os.urandom(16) for _ in range(stage)] for i in range(stage): print(f"Stage {i + 1}") print(f"My hashed password : {stronghash(pw[i]).hex()}") msg = bytes.fromhex(input("Guess my password(hex) > ")) if stronghash(msg) != stronghash(pw[i]): exit("Get out stranger! ୧(๑•̀ᗝ•́)૭") print('Here is your flag, master.') give_flag()
이거 보면 pw가 os.urandom(16) 으로 작성된 것을 알 수 있다. 근데 이게 사실 2^16이 별로 안 크다…짜잔
일단 왜 이문제가 또 bruteforce로 풀어야되는지 알려주겠다.
일단 현재 sha256은 one way hash func으로 다시 역산하는 것이 사실상 많이 어렵다.
그래서 처음에 이걸 알고서 아 그러면 하나 하나 비교해야되겠다!! 이랬는데 순간 머리에서 2^16이 아니라 10^16을 생각하면서 어? 이거 어트케 푸냐
이러고 있었다. 담부턴 이런 상황은 없을 듯 머리에 크게 남았음.
하튼 bruteforce로 간단히 짜면 아래와 같이 나온다
PY</>
from Cryptodome.Cipher import AESfrom Cryptodome.Util.Padding import pad, unpadfrom Cryptodome.Util.number import long_to_bytesimport osimport hashlibimport itertoolsimport stringfrom pwn import *def stronghash(msg: bytes) -> bytes: hashed_msg = pad(msg, 16) for _ in "Stronger!!": hashed_msg = AES.new(hashed_msg[:16], AES.MODE_ECB).encrypt(hashed_msg) for length in range(2, 16): md5 = hashlib.md5(hashed_msg[:length]) hashed_msg = md5.digest() for length in range(16, 32): sha256 = hashlib.sha256(hashed_msg[:length]) hashed_msg = sha256.digest() return hashed_msghash_values = {}for i in range((2 << 16)): value = long_to_bytes(i) hash_value = stronghash(value) hash_values[hash_value] = valuep = remote("host3.dreamhack.games", 16226)start = 2<<16for i in range(100): hash_value = p.recvline_contains(b": ").replace(b"My hashed password : ", b"") print(hash_value) # print(bytes.fromhex(hash_value)) # print(hash_value key = bytes.fromhex(hash_value.decode()) if key in hash_values: p.sendline(hash_values[bytes.fromhex(hash_value.decode())].hex()) print(hash_values[bytes.fromhex(hash_value.decode())].hex()) else: for i in range(start, (2 << 128)): if stronghash(long_to_bytes(i)) == key: p.sendline(long_to_bytes(i).hex()) print(str(hex(i))[2:]) breakp.interactive()