풀다가 하도 막히길래 ezbeat님이 풀이 업로드해주신다는데 새 글이 안올라오네요 ㅠ 그래서 그냥 풀어서 풀이 올려봅니다.
독자분들 배려해서 문제, 힌트, 풀이, 키는 나누었으며 각각 섹션은 가렸습니다.
Prob
o. 코드게이트에 오신 해커분들에게..
안녕하십까. 전 천문학자입니다.
몇 일전 한국에 살고 있는 한 소년이 지구 종말에 관련된 단서라고 파일
을 보내주었습니다. 곧 북극에 행성이 떨어질 거라고 하더군요. 무슨 말인
지 잘 몰라 프로그램을 분석해봐야알겠지만 안타깝게도 전 컴퓨터를 전혀
할 줄 모릅니다.
여러분들은 세계적인 해커들이라고 알고 있습니다. 부디 이 파일을 분석해
북극에 행성이 떨어지는 시기와 소년이 전하고 싶었던 메시지를 밝혀주세
요. 미래가 여러분들의 손에 달려있습니다.
From. 천문학자
답 인증 폼: YYYY_MM_DD_HH_MESSAGE
예) 2004_03_12_19_I can n0t h3lp y0u
SHA1 value of the correct answer : d8d82f025c5e9b2c82c3824b9bc328bdc55c645a
Hint
1. 커널보다는 exe에 중점을 둔다. (exe만 분석해도 풀 수는 있다.) 2. 커널과 exe의 공통함수를 찾아본다. 3. 자신 시스템 UI를 잘 관찰 한다. (시간 관련 함수를 다 뒤져본다) 4. *행성 충돌 시 특정 이벤트는 없다. (행성 충돌 루틴에 미련을 버리자) 5. *시각은 문제 내에 코딩 되어 있지 않으며 풀이자가 구해야 한다. (바이너리 분석만으로는 구할 수 없다.) 6. *문제 내에 지구는 몇 번이고 멸망한다. (자연과학적으로 접근해야한다)
복잡한 알고리즘 분석을 하지 않아도 되며 문제 의도를 파악하면 매우 쉽게 풀수 있는 문제입니다.
필자는 메시지는 빨리 찾았으나 의도 파악을 하지 못해 시각을 구하는데 늦게 걸렸네요
Solve
커널이라고 32비트에서 실행하라는데 커널은 필요 없다. 실행하면 패스워드를 입력하라고 한다.
드라이버를 로드하고 DeviceIOControl로 커널과 통신하며 인증을 수행하는데, 사실 이것도 필요 없다. (패스워드 소스코드는 첨부했습니다)
E8 00 00 00 00 이 Anti-Disassembly라고 모두 지우면 안된다. E8 00 00 00 00 중에 의심스러운게 하나 보인다.
[eax-5],cl / [eax-3],41/ [eax-2],9BE) 등 자신의 코드 영역에 write를 시도하는 루틴을 발견 할 수 있다.
원래 이 부분은 커널에 똑같이 존재하던 루틴이다. (패스워드 인증 루틴도 이 바이너리에 존재한다. IOCTL체크 부분까지 존재한다). (필자는 커널까지 다 분석한 뒤에야 여기에도 똑같이 있다는걸 알았다 ㅠ,)
커널에서 이 코드를 실행 하지만 이 바이너리에선 실행하지 않는다. (출제자 분이 의도적으로 넣어주신 것 같다.) 올리디버거로 점프 시키거나 치트엔진으로 쓰레드를 생성시켜 실행해보면 라는 스트링을 볼수 있는데 이것이 메시지이다. 메시지는 찾았다.
이제행성이 충돌하는 시각을 찾아야한다. (이 부분에서 제일 헤맸다) 바이너리 코드 자체에 시각은 없다. 자연적으로 접근해야한다.
먼저 시간과 관련된 함수를 모두 뒤져보았다. GetLocalTime 함수를 호출하는걸 발견했다.
이렇게시스템 시간을 바꾼다. 처음엔 이게 시각인줄 알았으나 아니였다.
정말 초자연적으로 생각해야한다.. 그런데 natural_satelite.bmp 자연위성(?)이 의심된다. 멍때리며 태양계를 보다보면 3바퀴 주기로 진짜 조그마한 점이 지구에 충돌하는걸 발견 할 수 있다. 그 시점을 찾기위해 치트엔진으로 지구와 소행성의 좌표를 바꿔보며 충돌 시점을 추측했다.
갈색이 충돌하는 소행성이다.
사진속에는 소행성이 보이지만 정확한 충돌 시점은 지구 중심속에 소행성이 있을때이다.
그 시점의 각도는 지구 360도, 소행성 320도이며 지구는 0.4도, 소행성은 0.72도 씩 공전한다.
우리가 천문학자도 아니고 충돌시각을 어떻게 구해라고 생각할 수 있겠지만 필자는 초등수학(비례식)으로 풀었다.
*가정
-충돌 시점
지구 : 360도
소행성 : 320도
-공전 속도
지구 : 0.4도
소행성 : 0.72도
지구 360도를 돌며 1회 공전한다.
지구가 1회 공전시 걸리는 시간은 1년이다.
가정은 끝났다.
-지구가(소행성이) 1회 이동시 걸리는 시간 :
360도:60초*60분*24시간*365일= 0.4도:x초 / 360: 31536000=0.4:x x = 35040초 -> 바이너리에선 한번 움직일 때 35040초씩 흐른다.
이제 식을 세워보자는 수학 따위 모른다. 코드부터 짜자.
초단위로 한이유는 Timestamp때문이다. Timestamp는 초를 기준으로 하기 때문에 날짜를 표현하는데 용이하다.
2013년 4월 3일 오전 3시일 때 Timestamp : 1364958000 이 Timestamp를 기준으로 하고, 우리가 지구를 0.4도씩, 소행성을 0.72도씩 공전시키되 똑 같은 시간인 35040초씩 흐르도록 시뮬레이터를 짜면된다.