문제


분석

두 개의 파일이 주어진다.

flag.txt는 문자가 이상하게 배열되어 있는 형태이고

oldschool.exe는 MS-DOS에서 구동하는 16-bit 프로그램이다.


flag.txt의 내용


oldschool.exe를 DOSBOX를 이용해서 실행해보았다.

총 18자리 16진수를 입력받고 희한한 그림을 그려준다...

저 그림은 입력에 따라 달라지는데,

아마 이 그림 출력결과가 flag.txt와 똑같이 만드는 것이 이번 challenge의 goal인 것으로 보인다.


oldschool.exe의 작동방식은, ida를 통해 분석할 수 있었다.

입력은 18자리 16진수를 넣는 것이고, 그림을 그리는 방식은 아래와 같다.

1. 그림을 그리는 공간은 17행 9열, 초기에는 모든 칸에 0이 저장돼있다.

2. 그림을 그리기 시작하는 위치는 5번째 행 9번째 칸

3. 16진수 두자리를 1바이트 수로 보았을 때, 해당 1바이트에서 LSB부터 2비트씩 검사함

4. 2비트가 00이면 왼쪽 위로, 01이면 오른쪽 위로, 10이면 왼쪽 아래로, 11이면 오른쪽 아래로 이동함.

   다만 1번째 줄에서는 위로 올라가지 않고 좌우 이동만 하고 마지막 줄에서도 마찬가지

   가장 왼쪽에 있을때도 왼쪽으로는 더 이상 이동하지 않고 가장 오른쪽에 있을때도 마찬가지.

5. 위치가 이동되었으면 그 칸에 저장된 값을 +1

- 그렇게 되면 총 36회의 이동이 일어남

6. 각 칸의 수들이 문자로 바뀌는데 그 방식은 다음과 같음.

특정 칸에 적힌 수가 i라면, ' p4{krule_ctf}'.index(i)에 해당하는 문자로 치환된다.

7. 만약 len(' p4{krule_ctf}')보다 큰 값이 적힌 곳이 있다면 해당 칸은 '^'로 치환된다.

8. 그림그리기를 시작한 곳은 'S'로, 그림그리기가 끝난 곳은 'E'로 치환된다.

이걸 어떻게 다 알아냈냐고?

그냥 찬찬히 ida로 어셈블리를 보면 된다.

그리고 len(' p4{krule_ctf}')문자열은 oldschool.exe를 HxD에 넣어봤는데 우연히 찾아내었다.

그리고 수차례의 테스트를 통해 해당 알고리즘이 정확함을 확신했다.

이제 flag.txt와 똑같이 그림을 그려주기만 하면 된다!


FL4G

주어진 그림과 똑같은 출력을 내도록 하는 입력값은 경우의 수가 매우 많다.

하지만 주최 측에서 알려준 flag의 형식은 p4{[0-9a-z]+}

flag는 oldschool.exe의 입력으로 들어가는 16진수를 hex decode한 결과라는 것도 알아내었다.

그렇다면 입력의 시작은 무조건 '70347B'이고 입력의 끝은 '7D'

이제 나머지 10개의 16진수만 알아내면 되는데...

hex decode되어 [0-9a-z]가 되려면 가능한 가짓수가 확 줄어든다.

그리하여 여러 시행착오 끝에 결국은 flag형식도 맞으면서 주어진 그림을 그려내는 입력을 찾아낼 수 있었다.



  FLAG : p4{4qib6}  

+ Recent posts