kleinvieh_2
This Challenge was covered in nullcon CTF 2025, this is a writeup.
Handouts
from Crypto.PublicKey import RSA
from Crypto.Util.number import bytes_to_long, long_to_bytes, inverse
import math
# Utility functions
def chunks(l : list, n : int):
"""Yield successive n-sized chunks from l."""
for i in range(0, len(l), n):
yield l[i:i + n]
# Encryption Methods
def encrypt1(message : bytes, key):
return pow(bytes_to_long(message), key.e, key.n)
def encrypt2(message : bytes, key):
r = 6882340053480090463606763880215995523230790077054797279541
48955984833460337936950913921276804334830417982234720038650432
72978049851415599561893741257560419681569060516183575560934138
10921455481533129431196963983261449026392268314712005423371052
82064399184931676924592908530791494346900227871404063095592748
76429602825553057727865668046378265513942121930242289966766533
92778247184219018318170431595521322520169452263706772780674245
06514993298100924479619565269428391036310378044733517453768164
25265593111120208943269707894718448626786594313865983615593934
31347384089724269793291585060272806532093184794138952597743198
48662706808171929571545923310500352950348748809789292920278241
36201527896331548177702899734448017201096029400209857898946908
92940225901348239139368695489071252944474774307390967674740264
01347928008150737871869441842515706902681140123776591020038755
23464218469985651732600457439392216291883939633654162021229687
08326595761950104668967012490038085535608952398604541628467596
35434691728716499056221797005696650174933343585361153344017021
74782738919340566707333344356965956756224740628328245128415514
97807379047609899109445504993166551283948992292847965847871986
89342431338201610314893908441661953172106881929330452489260
return pow(bytes_to_long(message) * r, key.e, key.n)
def encrypt3(message : bytes, key):
bytelength = int(math.floor(math.log2(key.n))) // 8
msg = message + b'\x00' * (bytelength - len(message))
return pow(bytes_to_long(msg), key.e, key.n)
def encrypt4(message : bytes, key):
bytelength = int(math.floor(math.log2(key.n))) // 8
msg = message * (bytelength // len(message))
return pow(bytes_to_long(msg), key.e, key.n)
def encrypt5(message : bytes, key):
bytelength = int(math.floor(math.log2(key.n))) // 8
msg = b'\x42' * (bytelength - len(message)) + message
return pow(bytes_to_long(msg), key.e, key.n)
# Actual code
flag = open('flag.txt','r').read()
messages = [x for x in chunks(flag.encode(), len(flag) // 5 + 1)]
key = RSA.generate(4096, e = 3)
key_file = open('pubkey.pem','wb')
key_file.write(key.public_key().export_key())
key_file.close()
encryptors = [encrypt1,encrypt2,encrypt3,encrypt4,encrypt5]
for i in range(5):
print(encryptors[i](messages[i], key))
Analysis & Solver
encrypt1
encrypt2
Coppersmith's Method
encrypt3
encrypt4

Representing the Repeated Message as an Integer
encrypt5

Last updated