본문 바로가기

CTF

[Codegate final 2018] Shall We Dance

플래그는 소문자이며 공백은 없다고 쓰여있습니다.

그리고 프로그램을 실행시킬땐 이어폰이나 헤드셋을 착용해달라고 하네요.

노래가 나오는 실행파일인 것 같습니다~!


메뉴는 총 3개로

1. Yes. Let's dance ~

2. I'm sorry. I have an another partner:(

3. I want to go home. -_-;


1번을 입력하면 4종류의 음악을 선택할 수 있습니다.


하지만 음악중 4번 tango를 입력하였을땐 파일이 깨졌다고 나오면서 노래가 나오지 않습니다.

뭔가 tango.wav 파일을 고친다면 flag를 얻을 수 있을거라고 생각하고 ollydbg 켜서 분석하였습니다.


string이 검색되므로 해당 함수에 쉽게 찾아갈 수 있습니다.

여기서 좀 더 내려가보면


이러한 코드가 보이는데 [3D7DD8] 주소에 입력값을 저장해 EAX로 불러와 각각의 선택지로 점프합니다.

요기서 중요하게 볼 부분은 아래와 같습니다.

MOV ESI,DWORD PTR DS:[3D7DC8] (jazz.wav)
MOV ESI,DWORD PTR DS:[3D7DCC] (samba.wav)
MOV ESI,DWORD PTR DS:[3D7DD0] (disco.wav)
MOV ESI,DWORD PTR DS:[3D7DD4] (tango.wav)

프로그램을 실행시키고 MOV ESI,DWORD PTR DS:[3D7DC8] 부분에 breakpoint 걸어서 주소값을 dump 떠보았습니다.


!! .wav 파일의 헤더 구조가 보입니다.

그렇다면 깨진파일인 tango.wav 파일의 헤더구조를 보면 아래와 같은 구조가 나타납니다.


위에 있는 jazz.wav 파일 구조와 별 다를게 없어보이지만 고정값인 "data" 문자열이 옆으로 밀린걸 보아 파일이 깨진걸 확인할 수 있습니다.

그래서 저는 .wav 파일 구조에 대해서 알아보았습니다.


.wav 구조에 대한 이미지 검색결과

wav 파일의 구조는 위처럼 크게 3가지로 나눌 수 있습니다. 

하나씩 상세히 살펴보기위해 tango.wav 파일의 44byte 값을 가져와 분석하였습니다.

분석 참고 사이트 (유리 상자 속 이야기님)


1. Chunk ID (4byte) (big endian)

 이 부분에는 "RIFF" 이라는 문자열이 들어갑니다. 

 wav 파일에 대한 고정 값이므로 변하면 안됩니다.


2. Chunk Size (4byte) (little endian)

 이 부분에는 ChunkID, ChunkSize 둘의 8byte값을 제외한 파일 전체 사이즈값이 들어갑니다.

 주의할 점은 little endian으로 들어갑니다.

tango.wav 의 사이즈는 0x108F2C 입니다.


3. Format (4byte) (big endian)

 파일 형식을 나타내는 문자열 "WAVE"가 들어갑니다.

 wav 파일에 대한 고정 값이므로 변하면 안됩니다.



1. Sub Chunk ID (4byte) (big endian)

 이 부분에는 "fmt " 이라는 고정 문자열이 들어갑니다. 

 * ftm + (space) 로 뒤에 스페이스값이 들어갑니다.


2. Sub Chunk Size (4byte) (little endian)

 Header 에서 뒤에 이어지는 값들의 사이즈입니다.

 이 부분도 고정입니다.

jazz.wav 파일도 추출해본 결과 jazz.wav 파일의 Sub Chunk Size는 10 00 00 00 이므로

tango.wav 파일의 Sub Chucnk Size를 12 00 00 00 에서 -> 10 00 00 00 으로 바꿔주었습니다.


3. Audio Format (2byte) (little endian)

 PCM 인 경우에 고정값으로 1이 사용된다고 하는데, 대부분 wave 파일은 PCM 이기 때문에 1이 들어갑니다.


4. Number Of Channel (2byte) (little endian)

 음성파일의 채널 수 입니다.

 mono 라면 1 이고, stereo 라면 2가 됩니다.


5. Sample Rate (4byte) (little endian)

 Number of Samples Per Second 입니다. Hz 단위로 표시합니다.

 쉽게 설명하자면, 1초 동안의 소리를 몇 개의 조각으로 쪼개서 저장(분석)하는가 입니다.

 10 Hz 라고 하면, 0.1 초 단위로 정보를 저장한다는 거겠지요. 당연히 숫자값이 커질수록 음질이 좋아집니다.


6. Byte Rate (4byte) (little endian)

 Average Bytes Per Second 입니다. 1초 동안 소리를 내는데 필요한 byte 수라고 생각하시면 됩니다.

 일단 위에 Sample Rate 가 441000 이고, mono 채널이라고 가정해 봅시다.

 그럼 기본적으로 1초 재생에 필요한 byte 수는 아래와 같습니다.

 (Sample 1개가 차지하는 byte) x (1초당 Sample 수) x (채널 수)

 = (Sample 1개가 차지하는 byte) x 441000 x 1

 그렇다면 (Sample 1개가 차지하는 byte) 가 무엇일까요? 

 가장 마지막에 나오는 field 인 'Bits Per Sample' 이 바로 그것입니다. 그때 설명하겠습니다.

tango.wav 파일의 Byte Rate 부분이 00 00 00 00 으로 비워져 있으므로 

jazz.wav 파일의 Byte Rate값 10 B1 02 00 을 사용하였습니다.


7. Block Align (2byte) (little endian)

 Sample Frame 의 크기입니다. Sample 1개의 크기가 아니라, Sample Frame 의 크리란 말입니다.

 mono 면 'sample 크기 x 1' 이고, stereo 면 'sample 크기 x 2' 가 되겠습니다.


8. Bit Per Sample (2byte) (little endian)

 Sample 한 개를 몇 bit 로 나타낼 것이냐 입니다.

 다른말로 Bit Depth 라고도 말합니다.

 쉽게 말해서, '도레미파솔라시도' 는 총 음이 8가지 입니다. 이 경우는 2의 3승(8)이고 비트로 나타내면 3 이 됩니다.

 이 값이 8 이라면, 2의 8승인 256 이 되겠네요. 순간의 소리를 256 레벨로 표현한다는 것입니다.

 이 값이 16 이라면, 2의 16 승개의 레벨로 순간의 음을 나타내겠다는 것이고요.

 당연히 이 값이 클수록 음질이 좋아집니다.


1. Sub Chunk2 ID (4byte) (big endian)

 이 값은 고정값으로서 'data' 라는 문자가 ASCII 로 들어가 있습니다.

tango.wav Sub Chunk2 ID 를 기준으로 data 고정값이 뒤로 2칸씩 밀려있는데 앞에 2byte를 지워 앞으로 2칸씩 땡겨주고

Sub Chunk2 Size 뒤에 00 00 을 추가하여 size를 맞춰주었습니다.


2. Sub Chunk2 Size (4byte) (little endian)

 뒤이어 나올 data 의 size 입니다.

 즉, 소리 정보가 들어있는 data 의 실제 size 라고 생각하시면 됩니다.

 파일 전체크기에서 header 를 제외한 크기겠지요.


위 내용을 요약하여 바꾼 내용을 ollydbg로 본다면 아래와 같습니다.

(수정 전)


(수정 후)


위와 같이 tango.wav 파일을 수정한 후 binary copy 하여 hexeditor 로 옮긴 후 파일 추출하여 들어보면 flag가 들립니다!


Flag is myfavoritemusicisjazz

'CTF' 카테고리의 다른 글

[Hitb-xctf 2018] multicheck  (0) 2018.05.13
CODEGATE 2018 본선 후기  (1) 2018.04.06
[Codegate final 2018] G0Crack  (0) 2018.04.06
[Codegate final 2018] betting  (0) 2018.04.06
[Codegate 2017] Goversing  (0) 2018.03.29