update writeup

This commit is contained in:
aaron
2021-12-04 02:47:19 +01:00
parent 81c25acdc3
commit f36d382b4c
2 changed files with 57 additions and 21 deletions

View File

@@ -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