이 CTF에서 XOR 암호가 2개 나왔는데, 하나는 키 길이가 주어졌다. (키길이는 9였다)

암호문이 충분히 길었기에 alphabet scoring 방식으로 풀었는데...


나머지 하나가 풀기에 상당히 까다롭게 나왔다.



secret 파일과 flag 파일, 그리고 이를 암호화한 python 소스코드가 주어진다.


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
#!/usr/bin/env python2
 
import random
 
def do_xor(p, k):
    out = ''
    for i in xrange(len(p)):
        out += chr(ord(p[i]) ^ ord(k[i]))
    return out
 
 
with open('flag_plaintext''rb') as f1:
    p1 = ''.join(f1.readlines())
 
with open('secret_plaintext''rb') as f2:
    p2 = ''.join(f2.readlines())
 
= max(len(p1), len(p2))
 
key = ''.join([chr(random.randint(0256)) for i in xrange(l)])
 
c1 = do_xor(p1, key)
c2 = do_xor(p2, key)
 
with open('flag''wb') as f1:
    f1.write(c1)
 
with open('secret''wb') as f2:
    f2.write(c2)
 
cs


secret_plaintext 파일과 flag_plaintext 파일을 읽어 둘 중 긴 길이만큼 랜덤한 key를 만들어내고, 이와 xor하여 secret과 flag파일을 만들어낸다.

언듯보기에는 XOR암호가 OTP에 쓰여 깰 수 있을 것 같지않다.


하지만 동일한 XOR키스트림을 두 파일에 썻기때문에


ciphertext1 = key ^ flag ciphertext2 = key ^ secret

ciphertext2 ^ ciphertext1 = key ^ secret ^ key ^ flag = secret ^ flag


위 공식이 성립한다. 즉 secret ^ flag 를 획득 할 수 있다. 그리고 우리는 flag 포맷을 알고있고, 그 포맷이 TUCTF{ 로 구성되어있다는 것을 알고있다.

그러므로 위 secret ^ flag에서 TUCTF{ 가 들어갈 부분과 secret부분을 얻을 수 있을것이다...


물론 여기서부터는 거의 secret과 flag의 추측을 통해서 문제풀이가 이루어진다..

이에 적절한 파이썬 스크립트가 있어서 사용해보았다.


cribdrag 라고 DEF CON 21에서 발표된 예측 가능한 키와 XOR암호문에 대한 cribdrag 공격을 수행하기위한 스크립트라고한다.


아래와 같은 경우 사용할 수 있다.


* 키가 재사용되는 일회성 원타임패드 (두 개의 암호문을 XOR하여 사용)

* 키가 재상용된 모든 스트림 암호 (위와 동일)

* 단일 문자 XOR암호

* 복수 문자 XOR암호


그래서 이를 이용해서 문제를 풀어볼 수 있다.

먼저 flag와 secret의 앞부분을 동일한 크기만큼 가져와서 xorstrings.py를 이용해 xor하여 랜덤한 키부분은 제거해준다.


python xorstrings.py 468A4376450DF466CD200E20C8D62D9C7E62B982A3625F7017EC97FEC4B7F38F4D3FE2E60439F1B8316BF96A7B64E2FBB2FCB5179CCA6001C14794E74A5DF146AD9FE58FB5091EE8BCE96E245A6A6C9B19886A9D3EC1C12C7C07BF99CB8D1351D38491E4E2C4D2C8BD526D94CD 6C9B4570450CE630C9201F20CECA68892B70B881B42505411CBCD1E2D3F4F5825062E2D10E34A4A96566D95A595C84ED8FEC8826A0ED5646ED3DFC9D732EBC64EBE0CFCE897634B781DD53020E155EDB74CF5DB97EB2F4715751EEC7C48D125D818492F0F785C8CEA51D3EB3A8 



이제, 그걸 cribdrag.py에 넣고... 예측되는 message를 입력하여 계속 예측해나가면 된다.



예를 들어 TUCTF{를 입력하면 가능한 출력가능한 문자열을 출력해주는데

여기서 teal m이 가장 유력해보이므로 42를 선택해주면 된다.



이런식으로 커맨드라인에서 계속해서 추측해나가면 된다.







이것말고도 단일XOR암호나 다중XOR암호에서도 쓰일 수 있어서... 꽤나 편리하다. 나중에 또 써먹어야지




+ Recent posts