update writeup
This commit is contained in:
@@ -15,18 +15,49 @@ HTB{4ff1n3_c1ph3r_15_51mpl3_m47h5}
|
||||
|
||||
## How to solve
|
||||
|
||||
See `decrypt.py`
|
||||
- It's a known plaintext attack.
|
||||
- The encryption works by applying `(a*byte+b)%n` for each byte of the pdf.
|
||||
- Where `a` and `b` remain static across the whole file.
|
||||
- The PDFv5 Header is known (`00000000: 2550 4446 2d31 2e35 0a25 e2e3 cfd3 0a37 %PDF-1.5.%.....7`)
|
||||
- Constraint 1: Factor `a` has to be a number between 1..256 while not sharing a common divisor with 256
|
||||
- Constraitn 2: Factor `b` has to be a number between 1..256
|
||||
- So it's possible to attack the encryption by iterating and trying to create a pair (a, b) that matches the entire encrypted pdf header.
|
||||
|
||||
## Progress
|
||||
```python
|
||||
def get_factors(ct, n=256):
|
||||
''' find a and b for n and ct '''
|
||||
# first generate a list of all numbers without common divisor with 256
|
||||
nogcds = [ x for x in range(1, n) if gcd(x, n) == 1 ]
|
||||
for b in range(1, n):
|
||||
for a in nogcds:
|
||||
for i, enc in enumerate(header):
|
||||
candidate = (a * enc + b) % n
|
||||
if candidate != ct[i]: break
|
||||
if(i+1 == len(header)):
|
||||
print(f'Solved: a={a},b={b}')
|
||||
return (a,b)
|
||||
print(f'No solution found.')
|
||||
return (0,0)
|
||||
```
|
||||
|
||||
### Code analysis:
|
||||
- When the factors are found, simply create a lookup table of all values and substitute each byte in the ciphertext.
|
||||
|
||||
```python
|
||||
def decrypt(ct):
|
||||
''' decrypt the file using the lookup table '''
|
||||
res = b''
|
||||
for byte in ct:
|
||||
dec = lookup[byte]
|
||||
res += bytes([dec])
|
||||
return res
|
||||
```
|
||||
## Notes
|
||||
|
||||
### Encryption code analysis:
|
||||
- Choose a `randint` `a` from `1` to `mod`, that is not divisible by mod.
|
||||
- Choose a `randint` `b` from `1` to `mod`.
|
||||
- for each byte in `dt`
|
||||
- calculate `(a * byte + b) % mod`
|
||||
- append to output bytes
|
||||
- return bytes when done
|
||||
|
||||
### Notes
|
||||
|
||||
- `s_next = (a * s_prev + b) mod p` is a linear congruential generator
|
||||
- `s_next = (a * s_prev + b) mod p` is a linear congruential generator prng
|
||||
|
||||
Reference in New Issue
Block a user