티스토리 뷰

최종 수정: 2014-10-11


안녕하세요. Hackability 입니다.


오늘 포스팅 내용은 2014 SU CTF에서 Crypto 100pt로 출제된 Huge Key 문제입니다. 문제 내용과 파일은 아래 첨부 하였습니다.


hugekey.tar.gz

Find the flag.


먼저 .tar.gz 으로 압축되어 있기 때문에 아래 그림 처럼 gunzip 명령으로 .gz을 해제 한 뒤, tar xf 명령으로 .tar를 해제 하면 ciphertext.bin파일과 encipher.php 파일이 나타나게 됩니다.


 

먼저, Ciphertext.bin을 hexdump로 살펴 보면 다음과 같습니다.


다음으로 encipher.php를 살펴 보면 다음과 같습니다.


php의 내용을 보면 flag.txt를 읽어 key값을 이용하여 암호화를 하는 php소스임을 알 수 있습니다.  mcrypt는 php에서 제공되는 암호 모듈로 MCRYPT_RIJNDAEL_128 옵션을 통해 AES 암호 알고리즘과 MCRYPT_MODE_CBC 옵션을 통해 CBC 운영 모드 암호화를 함을 알 수 있습니다. 문제는 랜덤한 iv 값인데, 15번째 라인을 보면 친절하게 랜덤하게 생성된 iv값을 암호문 앞에 넣어서 보내주는 것을 확인할 수 있습니다. 이로써, key만 알 수 있다면 암호문을 평문으로 복호화 할 수 있을 것 같습니다.


이 문제의 취약점은 foreach문에 있습니다. foreach 문을 자세히 보면 실제 key는 16바이트 이지만 실제로 변경되는 키는 2바이트 뿐이 변경이 되질 않습니다. foreach 문의 str_split($hugekey, 2)는 2바이트 단위씩 끊어서 $block으로 전송을 하고, key와 block의 0번, 1번 인덱스의 값만 계속 xor 하기 때문에 결과적으로 2바이트의 값만 변경이 되고 나머지 14바이트 키 값은 모두 \x00으로 채워지게 될 것 입니다.


암호화문을 복호화 하기 위해 iv, key(랜덤한 2바이트는 추측이 필요), encrypted msg가 있기 때문에 복호화를 할 수 있을 것 같습니다.


2바이트는 2^16이기 때문에 65536 번의 무작위 대입을 통해 결과값을 도출 할 수 있습니다. 또한, 복호화된 값이 Readable (Printable) 한 메시지가 아닌 내용을 제거 하면 우리가 찾아야 하는 답을 빠르게 찾을 수 있을 것 같습니다.


위의 내용을 파이썬 코드로 작성하면 다음과 같습니다. 사용된 PyCrypto모듈은 기존의 포스팅인 [2014 SU CTF Reverse 200 Commercial Application] 을 참고해주세요.  



먼저 iv값과 enc 값은 ciphertext.txt에서 가져온 내용입니다. 이 코드에서는 우리가 알지 못하는 key 변수의 최초 2바이트를 무작위 대입을 통해 구하는 것이 포인트 입니다. 19번째 라인에서 무작위 대입을 위한 스트링을 만들고 복호화를 한뒤 24~27번째 라인에서 Readable 한 내용인지 확인하게 됩니다. 만약 복호화된 모든 Character 들이 Readable 하다면 출력을 하고 종료하게 됩니다. (생각해보니 종료 하는 부분은 빼는게 더 좋을것 같네요. 그 뒤에 또 다른 플레그가 있을 수도 있으니...)


위의 파이썬 코드를 실행하면 다음과 같습니다.


FLAG: e3565503fb4be929a214a9e719830d4e

댓글