CTF | wargame

hackcenter / Two Time Pad (동일한 key를 사용한 이미지 OTP)

nopdata 2017. 3. 7. 20:45

My new encryption (two-time pad, under patent review) is twice as secure as one time pads. I am so certain about the security of my new scheme that I am releasing the encrypted versions of my two most secret pictures: Picture 1 and Picture 2

 HINTS

The image were encrypted with the same key K as such: encrypted_pixels[i] = pixels[i] XOR K[i].

두 개의 bmp 파일이 주어진다. 하지만 열어보면 모두 볼 수 없다. 힌트로 중요한 단서가 나왔는데 두 사진 모두 같은 key와 xor연산을 했다는 것이다.
bmp파일의 크기는 (600, 100)으로 동일하다. 


a ^ b = c
a ^ d = e
(a ^ b) ^ (a ^ d) = c ^ e
-> b ^ d = c ^ e

xor 연산은 위와 같은 식이 성립된다. 식만 세워놓고 보니 결국엔 본래의 key인 a를 구하지 못하는 것이 아닌가... 하고 고민을 했는데 b ^ d 는 b, d 모두 사진이므로 사진을 xor한 결과가 출력 될 것이고, xor 연산을 하더라도 사진이 정상이라면 볼 수 있다고 한다.

해서 두 개의 사진을 png형태로 다시 convert 하고 xor연산을 해서 사진을 추출하면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
from PIL import Image
 
import os
 
 
 
def tup_xor(val1, val2):
    res = list()
    for i in range(len(val1)):
        res.append(val1[i] ^ val2[i])
    return tuple(res)
 
 
img1 = Image.open('enc1.bmp')
img2 = Image.open('enc2.bmp')
 
 
try:
    img1 = img1.convert("RGB")
 
except:
    pass
 
 
 
try:
    img2 = img2.convert("RGB")
 
except:
    pass
 
res = Image.new("RGB",(600,100),(200,200,200))
 
 
for y in range(img1.size[1]):
    for x in range(img1.size[0]):
        res.putpixel((x,y),tup_xor(img1.getpixel((x,y)),img2.getpixel((x,y))))
 
 
f=open('result.png','wb')
res.save(f)
f.close()
os.system('result.png')
cs


그 결과로 두 사진이 xor된 flag 사진을 얻을 수 있다.


flag : dont_reuse_your_OTP_d9766aeb