473 words
2 minutes
[DreamHack] stroooooooong-hash
일단 문제 코드는 딱 하나만 집중해서 보면 된다.
from Cryptodome.Cipher import AES
from Cryptodome.Util.Padding import pad, unpad
import os
import hashlib
import itertools
import string
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_msg
요 stronghash 이 친군데.. 사실 아래 하나만 더 보자
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로 간단히 짜면 아래와 같이 나온다
from Cryptodome.Cipher import AES
from Cryptodome.Util.Padding import pad, unpad
from Cryptodome.Util.number import long_to_bytes
import os
import hashlib
import itertools
import string
from 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_msg
hash_values = {}
for i in range((2 << 16)):
value = long_to_bytes(i)
hash_value = stronghash(value)
hash_values[hash_value] = value
p = remote("host3.dreamhack.games", 16226)
start = 2<<16
for 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:])
break
p.interactive()
[DreamHack] stroooooooong-hash
https://compy07.github.io/Blog/posts/security/crypto/dreamhack/level_1/stroooooooong_hash/