arrow-left

All pages
gitbookPowered by GitBook
1 of 1

Loading...

Xmas Spirit

hashtag
Contents

We get given challenge.py and encrypted.bin. Analysing challenge.py:

It calculates two random values, aaa and bbb. For every byte kkk in the plaintext file, it then calculates

ak+bmod  256ak + b \mod 256ak+bmod256

And appends the result of that as the encrypted character in encrypted.bin.

hashtag
Analysis

The plaintext file appears to be letter.pdf, and using this we can work out the values of and because we know the first 4 bytes of every PDF file are %PDF. We can extract the first two bytes of encrypted.bin and compare to the expected two bytes:

Gives us

So we can form two equations here using this information:

We subtract (2) from (1) to get that

And we can multiply both sides by the modular multiplicative inverse of 43, i.e. , which is , to get that

And then we can calculate :

hashtag
Solution

So now we have the values for and , it's simply a matter of going byte-by-byte and reversing it. I created a simple Sage script to do this with me, and it took a bit of time to run but eventually got the flag.

And the resulting PDF has the flag HTB{4ff1n3_c1ph3r_15_51mpl3_m47h5} within.

import random
from math import gcd

def encrypt(dt):
	mod = 256
	while True:
		a = random.randint(1, mod)
		if gcd(a, mod) == 1:
			break
	b = random.randint(1, mod)

	res = b''
	for byte in dt:
		enc = (a * byte + b) % mod
		res += bytes([enc])
	return res


dt = open('letter.pdf', 'rb').read()

res = encrypt(dt)

f = open('encrypted.bin', 'wb')
f.write(res)
f.close()
aaa
bbb
a⋅37+b≡13mod  256a⋅80+b≡112mod  256a \cdot 37 + b \equiv 13 \mod 256 \\ a \cdot 80 + b \equiv 112 \mod 256a⋅37+b≡13mod256a⋅80+b≡112mod256
43a≡99mod  25643a \equiv 99 \mod 25643a≡99mod256
43−1mod  25643^{-1} \mod 25643−1mod256
131131131
a≡99⋅131≡169mod  256a \equiv 99 \cdot 131 \equiv 169 \mod 256a≡99⋅131≡169mod256
bbb
b≡13−169∗37≡160mod  256b \equiv 13 - 169 * 37 \equiv 160 \mod 256b≡13−169∗37≡160mod256
aaa
bbb
with open('encrypted.bin', 'rb') as f:
    res = f.read()

print(res[0])
print(res[1])
print(ord('%'))
print(ord('P'))
13
112
37
80
with open('encrypted.bin', 'rb') as f:
    res = f.read()


final = b''


R = IntegerModRing(256)

for char in res:
    b = bytes([ (R(char) - R(160)) / R(169) ])
    print(b.decode('latin-1'), end='')
    final += b

with open('answer.pdf', 'wb') as f:
    f.write(final)