그냥 모든 농담을 하나씩 암호화해서 서버가 준 암호문과 비교하면 된다. 서버로부터 N, e, ciphertext를 받아 joke_list에 있는 모든 농담을 반복시킨다. 각 농담을 pow(message, e, N)을 사용해 암호화합니다. 결과가 서버가 준 ciphertext와 일치하면 정답이므로 찾아낸 농담을 서버에 전송하는 과정을 10번 반복하면 된다.
from pwn import *
from Crypto.Util.number import bytes_to_long, long_to_bytes
from jokes import joke_list
# p = process(['python3', 'server.py'])
p = remote('43.202.99.132', 18892)
def solve():
for i in range(10):
p.recvuntil(b'=== Challenge')
p.recvline()
log.info(f"Solving Challenge {i+1}/10")
# N, e, ciphertext 값 파싱
n_line = p.recvline().decode().strip()
e_line = p.recvline().decode().strip()
c_line = p.recvline().decode().strip()
N = int(n_line.split(' = ')[1], 16)
e = int(e_line.split(' = ')[1], 16)
ciphertext = int(c_line.split(': ')[1], 16)
log.info(f"N = {hex(N)}")
log.info(f"e = {hex(e)}")
log.info(f"Ciphertext = {hex(ciphertext)}")
# 메시지 공간(joke_list) 전체를 탐색
found_joke = None
for joke in joke_list:
# 각 농담을 서버가 했던 것과 똑같이 암호화
message_int = bytes_to_long(joke.encode())
encrypted_attempt = pow(message_int, e, N)
if encrypted_attempt == ciphertext:
found_joke = joke
log.success(f"Found the joke: {joke}")
break
p.sendlineafter(b'Enter the decrypted message: ', found_joke.encode())
# 10번 모두 성공 후 플래그 수신
p.recvuntil(b"Congratulations!")
flag = p.recvall().decode()
log.success(f"FLAG: {flag.strip()}")
if __name__ == "__main__":
solve()