이번 문제는
'이 프로그램은 몇 밀리세컨드 후에 종료되는가. 정답은 MD5로 변환'
프로그램을 실행하면
메세지 창이 뜨고 가만 있어도 얼마 뒤에는 자동으로 종료됩니다
내용을 보면 compressed, encrypted라는 문구가 있는것으로 보아 패킹되어 있는것으로 생각되는데요. 프로그램을 peid로 보면 아래와 같습니다
EP Section이 UPX1인것으로 보아 UPX라는 툴로 패킹이 되어있음을 알 수 있는데요,
UPX는 오픈 툴이므로 인터넷의 공식 홈페이지(http://upx.sourceforge.net/)에서 다운 받아
언팩하면 됩니다. 언팩 방법은 'upx -d [upx로 패킹된 파일]' 로 언팩이 가능합니다
이제 언팩된 프로그램을 올리디버거로 열고 실행하면 원래 메세지 박스가 뜨지 않고 아래와 같은 메세지 박스가 뜨게 됩니다
뭔가 디버깅을 방지하는 내용이 추가되어 있는것 같은데요,
올리디버거로 다시 열고 문자열을 검색해 해당 위치로 가면
IsDebuggerPresent 함수를 호출하는군요. IsDebuggerPresent 함수는 디버거 검색시 자주 사용되는 함수로 MSDN에서 원형을 찾아보면
'이 프로그램은 몇 밀리세컨드 후에 종료되는가. 정답은 MD5로 변환'
프로그램을 실행하면
올리디버거로 열어보면 아래와 같은 메세지 박스가 뜹니다
UPX는 오픈 툴이므로 인터넷의 공식 홈페이지(http://upx.sourceforge.net/)에서 다운 받아
언팩하면 됩니다. 언팩 방법은 'upx -d [upx로 패킹된 파일]' 로 언팩이 가능합니다
이제 언팩된 프로그램을 올리디버거로 열고 실행하면 원래 메세지 박스가 뜨지 않고 아래와 같은 메세지 박스가 뜨게 됩니다
올리디버거로 다시 열고 문자열을 검색해 해당 위치로 가면
59CEA211.00445A7A를 호출한 뒤 리턴된 값을 비교해 메세지 박스를 띄울지 결정하는 것이 보입니다.(빨간 박스) 59CEA211.00445A7A 함수의 내용은 다음과 같습니다
BOOL WINAPI IsDebuggerPresent(void);
이며 프로세스에 디버거가 붙어있을시 0이 아닌 값, 디버거가 안붙어있으면 0을 리턴합니다
현재 올리디버거로 열었으니 0이 아닌값이 리턴되겠죠?
그리고 위에서 봤던 빨간 박스에서 리턴값을 검사한 뒤에 아까 보았던 메세지 박스를 띄우는 부분으로 이동하겠죠
위의 빨간 박스의 'JE SHORT 59CEA211.004010D8'중에서 004010D8을 보면 아까의 메세지 박스 이후의 주소인것을 볼 수 있는데요, 그렇다면 명령어를 JE가 아닌 JMP로 바꿔버리면 메세지 박스를 띄우고 종료하는것이 아닌 원래의 코드를 탈것이라고 생각할 수 있습니다
해당 위치의 어셈블리 코드를 열어서 'JMP SHORT 59CEA211.004010D8'로 변경 뒤에 저장 후 다시 올리디버거로 엽니다
이제 원래의 문제를 생각해보면 메세지 박스를 띄우므로 관련 함수를 호출할것이라는 생각이 듭니다. 함수를 찾아 MessageBox 함수들에 전부 브레이크를 걸고 실행하다 보면 여기서 브레이크가 걸립니다찾았네요. 그런데 아래를 보니 시간을 무한대로 줘서 WaitForSingleObject 함수를 호출하고 기다렸다가 어디선가에서 메세지를 받으면 핸들을 닫아버리는군요
그 어딘가를 찾아야 되는데 MessageBoxW 위쪽을 보면 몇개의 인자를 스택에 넣고 453C44를 호출 한 뒤에 메세지 박스를 호출한것으로 봐서 뭔가 작업을 한뒤에 메세지 박스를 호출하는 것 같은데 가장 눈에 띄는 40DDEE 부분의 코드를 보면 다음과 같습니다코드의 설명은 주석을 참고해주시구요
여기서 중요한 부분은 'CMP EAX,DWORD PTR SS:[EBP+4]' 부분인데 [EBP+4]에 있는 0x27ED와 비교를 해서 EAX(경과시간)이 크면 버튼을 클릭한 효과를 발생시키는걸 볼 수 있습니다
따라서 원하는 밀리세컨드는 0x27ED, 10진수로 바꾸면 10221 밀리세컨드 입니다
이것을 MD5로 변환하면 문제가 원하는 답이 됩니다
Posted by ratiel