CodeEngn.com [Advanced] 1
이 일기는 어느 리버서의 삽질 일기입니다.
질문 하나 드리도록 하겠습니다.
여러분은 빨간 길과 파란 길을 선택할 수 있습니다.
빨간 길은 길이 험하고, 시간이 많이 걸립니다.
파란 길은 길이 평탄하고 시간도 적게 걸립니다.
여러분이라면 어떤 길을 선택하시겠습니까??
그 길을 선택한 후, 후회하지 않을 자신이 있나요?
파란 길(Write UP)
1. 여러분은 DIE(Detect It Easy)로 파일이 깝니다.
패킹 되어 있는 문제를 보고 깊은 감명을 받으세요.
2. upx307w 를 사용합시다.
명령어 팁 : 파일경로/upx -d [파일경로/파일이름]
언패커를 이용해서 언패킹 해줍니다.
(EP : 1770 입니다)
3. 한 번 실행을 해봅시다.
디버깅하지 않았을 경우
디버깅 했을 경우
이러한 패턴을 용의 눈으로 보고 Auto IT script를 썼구나를 파악합니다.
그리고 바로 디컴파일러를 찾는 겁니다.
4. 용의 구글링
"역시 최고의 검색 엔진, 구글!"을 외치며 디컴파일러를 다운로드합니다.
5. 디컴파일러 실행
Auto it script [MsgBox] Function 함수에 대한 설명
을 확인할 필요 없이
딱 봐도 답으로 보이는 13.179 초를 확인합니다.
밀리세컨트로 변환해서 MD5 암호화 사이트를 사용해서
문제 풀이 3분만에 답을 적출합니다.
빨간 길(WriteUp)
1 ~ 2번까지의 과정은 똑같습니다.
3. 힌트를 발견하지 못한다. (Auto IT Script로 작성했다는 힌트가 주어지지 않았다고 가정)
대회에서는 이런 힌트조차 주지 않는 경우가 다수입니다.
힌트를 가지지 않고 풀어봅시다.
4. IDA에서 Import 탭에서 시간에 관련된 함수를 찾아봅시다.
문제를 떠올려봅시다.
이 프로그램은 몇 밀리세컨드 후에 종료 되는가
정답인증은 MD5 해쉬값(대문자) 변환 후 인증하시오
시간(밀리세컨드)에 관련된 함수들이 사용될 확률이 높습니다.
시간에 관련된 함수들을 찾아보았습니다.
TimeGetTime : 윈도우가 시작하고 난 후 지난 시간을 얻는 함수
WaitForSingleObject : 스레드에서 특정 신호를 보낼 때까지 기다리는 함수
TimeGetTime 함수를 사용해서 프로그램 마지막 부분에서
실행된 시간을 측정하는 것이 가장 그럴듯한 시나리오인 듯 싶습니다.
여러분은 이를 통해 1시간 정도를 아낄 수 있습니다.
TimeGetTheTime 함수를 호출하는 함수의 그래프 개형입니다.
절대주소를 구해서 디버거로 이동합시다.
[444C3E....] 메모해 둡시다.
IsDebuggerPresent 함수로 분기점을 가르더군요.
test eax, eax 명령어에서 Eax 레지스터의 값을 0으로 패치해줍니다.
그 뒤로 쭉 트레이싱 하다 보면...
TimeGetTime을 호출하는 군요.
점프를 취하지 않습니다. 쭉쭉 넘어가 봅시다.
eax 레지스터의 값과 [ebx+4]의 값을 비교하더군요.
혹시나 해서 살펴봤더니 답이 여기 있었습니다.
총정리
제가 이 문제를 푸는데 3시간 정도가 걸렸습니다.
Auto It Script를 애써 무시하고
Import한 함수들도 안봤습니다.
디컴파일러는 사용하지 않고
IDA와 디버거로 트레이싱만 했습니다.
그리고 답을 발견했을 때 깨달았습니다.
이런 도구, 기능들을 이용해서 분석 시간을
줄인다면 어떠했을까?
레이어 7 CTF처럼 퍼스트 컨쿼러가 적용된 대회라면
CTF에서 리버싱 문제는 얼마나 빠르게 문제를 푸느냐에 따라서
"이득을 얼마나 얻을 수 있느냐"로 갈립니다.
즉, 플래그를 빠르게 도출해 내는 것이 중요합니다.
빨간 길과 파란 길의 차이는 분석 시간의 차이도 있지만
노련함의 차이인 듯 싶습니다.
악성코드 분석이 목적이신 분들은 재미로 ,
CTF Player님들은 "이런 풀이도 있구나"하며
봐주셨으면 좋겠습니다.