[Crypto]


The Game of DES


Ah exciting, Ah fun, the Game of DES!

Port number changed to 8080 to bypass firewall restrictions.

nc 175.123.252.137 8080

플래그를 내가 주는 횟수(단, 42회 이상)만큼 내가 주는 키로(단, 키의 모든 바이트가 달라야 함) 암호화해서 돌려주는 문제다.

엥 그거 그냥 하면 되는거 아닌가? 하는 당신을 Traceback이 반겨준다.

print("enc :", dat.decode())

암호화된 데이터를 그냥 byte 형태나 hex 형태로 주는 게 아니라, UTF-8로 디코딩해서 주려고 하기 때문에 오류가 발생한다.

유효한 UTF-8 문자열로 암호화될때까지 브루트포싱하면 어떨까? 그렇게 될 확률이 $2^{-80}$이다. CTF 수준에서 이런 걸 바라는 건 아닐거고…

DES는 Weak key와 Semi-weak key pair set를 가지고 있다. Weak key $\mathrm{K}$와 Semi-weak key pair set $\mathrm{\left\{K_1, K_2\right\}}$는 각각 다음 성질을 가지고 있다.

$$ \mathrm{E_K(E_K(P)) = P}\newline\mathrm{E_{K_1}(E_{K_2}(P)) = P}

$$

우리가 암호화할 플래그는 유효한 UTF-8 문자열이다. 따라서 이런 키로 암호화하게 되면 플래그가 그대로 나올 것이고, 플래그는 유효한 UTF-8 문자열이므로 오류 없이 출력될 것이다.

근데 문제는, 이런 키들은 같은 바이트를 여러 번 포함하고 있다는 것이다. 예를 들어 Semi-weak key pair set 중 하나가 {0x1FE01FE00EF10EF1, 0xE01FE01FF10EF10E}인데, 둘 다 동일한 바이트를 각각 두 개씩 포함하고 있다. 이 키를 그대로 집어넣으면 문제 조건을 만족하지 않을 것이다.

DES 키에서 각 바이트의 8비트 중 실제 암호화에 이용되는 건 MSB 7개이다. LSB 1개는 키의 무결성을 검증하는 데에만 쓰이는 Parity bit이다.

PyCrypto(dome) 문서를 읽어보자.

key – The secret key to use in the symmetric cipher. It must be 8 byte long. The parity bits will be ignored.