본문 바로가기

Let's Study/Hacker's CTF

[2014 화이트햇 콘테스트]Cold War

이번에 ctf풀면서 스터디하자! 하고 만들어진 Mr.Mr 팀입니다.

어쩌다보니 예선 일반부 9위까지 올라가게 됬네요.

문제풀이 시작하겠습니다.




주어진 건 이 소스코드와

(아. if __name__ = "__main__":

a = g(8) 에서 8이 아니라 n으로 주어졌습니다. 죄송합니다.)


fee304acd551a17fbd3b7f23c1e51fba9c55a93de43d797187fc1eaa9055ba74fc3e2c62d4ac10fe864fbb79f83c7822

f0e414aa9d5ebc3df2202c6dc8f85197d54caf6ebd267971c9e51fb9d54fa678bd226d64c2ff51aa9a5faf64bd332c60c6e014b0915abc3df4212c64c8e51fb9d554b878ef732d22

eeac15b1d555a169bd316d71c2ac10fe965aa27ee83e7970

f7e903ad9a55ee6ff8226962d3ff51b39c48ba7cf6372c62c9e851999a5fee7bf2206b6ad1e902fe9852bd69fc396922

eeac05b69c55a53de93a6923c9ed05b79a55af71bd337f70c2e113b28c1bb974f13e2c61c2ac15bb8652a973fc26696787ed02fe941ba67ce7337e67c8f902fe9954ad7ce93b636d

f3e414ad901ba972f2362c70c6f518b0921ba86ff23f2c50cfe51ffebd5aab3dde3a796f

f3e414fe9e5eb73df4212c6287ff19bfc41bb87cf1276923c8ea51aa9d5eee73fc3f6922

fee304fe8252a271bd20696ec6e51ffe9c55ee70e4726466c6fe05fe9354bc78eb377e22


알수없는 문자들입니다. 위의 코드를 보니 저 문자들은 인코딩된 문자들입니다.


소스코드를 돌려봐도 n이 정의되어있지 않다고 나오고. 당연한 결과이지만요.

소스코드를 차분히 분석해봅시다.


g(l) 함수가 하는 일은 l을 받아와서 그걸 0x00 ~ 0xff의 수 중 랜덤하게 바꿔서 r에 l만큼 붙여넣습니다. (join)

만약 l이 8이라면 r은 랜덤한 8바이트값이 있게 됩니다.


e(r, p) 함수가 하는 일은 아마도 g(l)에서 생성된 값과 input_messages에 들어있는 값을 나눠서 몫이 0으로 떨어지지 않는다면 

error를 출력하고 아닐경우 1바이트씩 xor하는 함수입니다.



이 소스코드는 비제네르 암호를 구현해놓은 건데 비제네르 암호에서는 mod를 사용하여 값을 바꾸지만 여기서는 xor로 대신하네요.




자세한 건 인터넷에 비제네르 암호 찾아보시면 나옵니다.


이 사실을 알았으니 적용해봅니다. 주어진 인코딩된 문자들은 12의 배수의 길이로 나열되있습니다.

첫문장부터

48, 72, 24, 48, 72, 36, 36, 36 글자이지요.


그 뜻은 g(n)에서 n이 12임을 의미합니다.

우리는 12바이트의 암호문을 알아내서 저 인코딩된 문자들과 xor하여 값을 알아내야 하는데


비제네르 암호에서 중요한 건 어떤 단어를 얼마나 많이 쓰냐 입니다.

우리가 편지든 뭐든 영어표현에서 가장 많이 쓰이는 건 you, the, is, I 인데

I는 한글자이기때문에 찾기가 힘들고 you, the, is를 이용해 규칙을 찾도록 합니다.


첫문장의 fee304 와 마지막 문장의 fee304, 6번째의 f3e414와 7번째의 f3e414가 3글자씩 겹치는 부분입니다.

이 말은, 똑같은 단어를 썼다는건데 fee304와 you를 xor해보면


값이 0x87, 0x8c, 0x71이 됩니다.

이걸가지고 인코딩된 문자들을 12바이트씩 끊어서 1,2,3번째 바이트와 xor을 하면 뭔가 그럴싸한 표현들이 보이기 시작합니다.

you, fin, whe, i d, per, i t, the, the, you, Nat, ......

이렇게 차근차근 xor해서 추리를 하다보면 12바이트의 암호문이 완성이 되고

그걸 파이썬 코드를 짜서 돌려보면 답이 나오게 됩니다.