constWORLDant

KISA Diary 문제풀이 및 상세분석 본문

0x02 Reverse Engineer/0x03. Etc

KISA Diary 문제풀이 및 상세분석

data type ConS_tanT 2018.05.18 22:29

팀원인 zer0day에게 바이너리를 우연히 받았다.  감사따리다~~ (grin)


오늘 받았으니 오늘 안에 끝내고 싶어서 집에서 분석을 하고, 잠시 밥을 먹으러 외출했다가 카페와서 마무리 하였다. (저번 키사문제도 맥주 한잔 하고 풀었는데.. 얘도 맥주 마시고 분석했다..맥주는 좋다.)


우선, 바이너리를 통해 반성을 해본 것이 있다.



1. 아직까지 WIN32API 분석 속도가 느린 점이다.

지금 까지 한 3개 정도의 프로그램을 분석해보았는데, 이 녀석은 핵심 심볼도 일부 지워져 있고,(MessageBox 얘만 살아있으면 되게 빨리 감을 잡았을 텐데..) 코드가 TEXT섹션과 CODE섹션에 병합되어 있는 형태여서 다소 생소하였다. 그리고 break point와 trace를 동시에 보는 눈이 부족했다.


2. 바이너리 안에 있는 모든 디렉터리를 열람하지 않았던 점이다. 해당 바이너리는 특정 파일을 로드하여 알림장(aka. 다이어리) 형태로 사용할 수 있는 바이너리인데, 프로그램을 설치한 경로 이외에 상위 경로에도 똑같은 디렉터리가 존재하는 것을 너무 늦게 알아차렸다. 하지만, 득 또한 있다. zer0day에게 질문하기 전에 해당 바이너리에 새로운 계정을 어떻게 추가하는지 동적분석을 해보았기 때문이다. 이 동적분석을 함으로써 내 머릿속의 win32api구조에 살이 붙어졌다고 확신한다.


3. 해당 바이너리에 Mutex가 걸려있는 사실을 너무 늦게 알아차렸다. 5분 정도 걸린 것 같다. OllyDBG, Immunity에서 breakpoint를 걸어두어도 Run을 실행하면 프로세스가 Terminated 상태로 전환되어 분석이 불가능하였다.

처음에 이것때문에 안티디버깅이 걸려있는 바이너리인가 싶어서 Module을 열어 함수들을 훑어보았는데 IsDebuggerPresent 밖에 없었다. 내 디버거는 IsDebuggerPresent는 자동 우회 되기 때문에 이건 백프로 나의 휴먼에러라 생각하고 작업표시줄을 열어 증상을 파악한 뒤 디버깅을 진행하게 되었다. 이 행위로 인해 피 같은 5분이 소요 되었다.


바이너리 분석을 해보자.


해당 바이너리는 setup.exe 부터 시작하게 된다.

어느 setup 마법사 인스톨러가 그렇듯이 NEXT를 갈겨주면 바이너리를 설치할 수 있다. 


디폴트 디렉터리가 c드라이버이기 때문에 ida에서 permission deny를 일으켜서 분석용 드라이버로 옮겨서 진행하였다.



이 바이너리는 UPX 패킹이 되어있었기에 가볍게 upx 언패킹을 진행하였다.


<인터페이스 분석>


바이너리를 키게 되면, 이런 화면이 나온다.


되게 깔끔한 인터페이스 이다. 

File ~ Help는 메뉴바이다. 

그리고 각 메뉴바에서 발견되는 메뉴들은 SubMemu라고 표현된다. 


File을 누르게 되면 이러한 SubMenu가 발견 된다.


계정이 아무것도 없다고 가정하고 New Diary를 클릭해보자.


되게 이쁜 서브 윈도우 혹은 Dialog가 뜨게 된다.



패스워드는 복사를 할 수 없는 기능이 있다.




이름을 입력할 수 있고, 패스워드를 입력할 수 있는데 특수문자도 되는 것을 동적으로 확인하였다.  

나중에 분석에서 볼 수 있지만 ASCII -> UNICODE로 변환되는 녀석이 있기 때문에 가능하다고 생각되었다.


다음은 Open Diary이다.


해당 바이너리는 특정 파일을 로드하여야만 사용할 수 있다.

시간이 있다면, 해당 확장자까지 공부를 하고 싶었지만, 다른 공부할 것도 오늘 많기 때문에 하지 않았다.

상기의 MyDiary.iDD파일이 키사에서 제공해주는 파일이자, 키 값이 들어있는 파일이며, 나머지 파일들은 테스트를 위해 내가 만든 파일이다.


다음은 MyDiary를 열기 위한 삽질의 과정이다.


< 동적 분석 > 


IDA를 잠시 열어서 어떤 문자열들이 있는지 보았는데 이 문자열들이 하나같이 하나의 함수에 매개변수들로 이용되는 것으로 보아 sub_404350은 특정 함수의 심볼이 지워진 것이라고 판단하고 분석을 진행해보았다.



0x404350에서 EBX,ESI,EDX,EAX 행위를 통해 액셀러레이터 및 바이너리에 사용되는 문자열들을 세팅하는 것을 보았다. 정확한 함수명은 모르겠다.


평소에 악성코드를 분석할 때 유심히 보는 API들 혹은, 그래픽에 쓰이는 API들에 Break Point를 미리 걸어두고 분석을 진행했다. 

이런 행위는 피카츄배구 삽질할 때 깨달은 내용이다. 확실히 이 방법은 API 프로그램 분석 시에는 도움이 된다.

다만, 심볼이 지워진 함수를 제대로 파악하지 못하는 실력이라 더뎠던 것을 제외하고는 말이다.





그림에서 잘 보이지 않으니 왜 저 함수들에 breakpoint를 걸게 되었는지 간단한 부연 설명을 해볼까 한다.


간단하게 요약해본다.

CreateWindowExA : WIN32API 혹은 MFC환경에서 부모윈도우든 자식윈도우든 해당 함수를 통해 호출된다.

바이너리를 인터페이스로만 분석한 결과 여러개의 윈도우를 사용하길래 각 윈도우의 호출 위치를 잡아서 상세 분석을 해보기 위함.


CreateFile : 함수 명만 해석하면 파일을 생성하는 것이지만, 윈도우즈에서 파일을 열 때 역시 CreateFile함수를 이용한다.


GetModuleFileName : 각 모듈마다 고유한 핸들이 있는데 그 핸들을 추출함으로써 이 기능이 어떤 클래스에 종속되어 있는지를 확인하기 위함이었음.

이 함수를 통해 해당 바이너리에 Panel과 Dialog가 어마어마하게 많이 있다는 것을 알게 되었음.


ShellExecuteA : 윈도우즈에는 WinExec와 ShellExecute종류가 있다. WinExec보다 ShellExecute가 더 강력한데 

관리자 권한으로 실행할 수 있기 때문이다. 하지만, 레지스트리는 직접적으로 수정을 하지 못한다. (경험)


MessageBoxA : win32api에서 절대 빠질 수 없는 녀석이다. 이는 디버깅 목적으로도 쓰이며, 사용자에게 프로그램 행위를 보다 간결하고 명확하게 보여주기

위함이다. 대체로 크랙미 같은 문제는 MessageBoxA를 기점으로 분석하면 시간 소요가 줄어든다. (경험)


GetSubMenu : 상기에서 서술했듯이 해당 프로그램의 구조는 Menu -> SubMenu 이다. 

분석에 주점이 되는 것은 Menu가 아닌 SubMenu이기 때문에 SubMenu에 bp를 걸었다. 


lstrcpy : 보통 WIN32API로 짜여진 악성코드에서 경로들을 복사할 때 주로 사용한다. 

해당 바이너리는 악성코드는 아니지만, 혹여나 경로를 수정하는 루틴이 있을 까봐 BP를 걸었다. 


ReadFile & WriteFile : 파일 입출력의 행위를 보기 위해 bp를 걸었다.


MessageBeep : 예상하지 못한 경로에 접근했을 때 발생할 것이라 판단하고 bp를 걸었다.


FindResourceA : pe구조를 살펴보았었는데, 리소스가 꽤나 많이 있길래 어떤 리소스를 받아오는지 궁금해서 bp를 걸었다.


심볼 없는 함수들 : 동적 분석 도중 디버깅이 원할하기 위해 느낌대로 bp를 걸었다. 


다이얼로그에 기입되는 문자열들은 Label로 쓰였으며 정확하게는 fmNewDiary.LabelN.Caption이었다. 이 녀석은 TEdit 클래스에 종속되었다.


다이얼로그에 붙여지는 순서는 다음과 같다.


Edit Handle(Your~,Enter~,Confirm) -> Button Handle(OK,CANCEL) ->  Do not(CheckBox) 추출


하나하나 연결지어보면 이러한 자식 윈도우이자 다이얼로그가 생성된다.


테스트를 위해 name과 password를 넣어보았다.




패스워드 길이 필터 없이 그대로 입력한 패스워드의 길이를 반환하는 것을 보았다.


아이디의 길이 역시 반환하는데 이는 EDX에 반환되었다.


첫 번째 입력 패스워드 백업 된 부분이다.


첫 번째 입력 패스워드와 두 번째 입력 된 패스워드의 일치여부를 판단하는 곳이다.


004043AF로 분기된 뒤 진행 되는 과정이다.

New Diary에 디버깅 해보았으니 이제 키사에서 주어지는 바이너리를 분석해보자.

디버깅 하다가 재밌는 사실도 발견했다.

백그라운드로 로그인 성공한 다이어리가 있다면 디버깅 할 때 인 인터페이스가 뜨는것이 아니라

그 로그인 계정으로 다이얼로그 창이 뜨게 된다.

그리고 모든 WIN32API 이벤트는 POSTMESSAGE를 호출 한 뒤에

자원이 들어오지 않으면 무한루프상태로 있게 된다.


위에서 만들어 진 계정



MyDiary.iDD 파일이 이번 문제의 핵심 파일이다.

바로 얘부터 분석했다면 시간 소요는 줄었겠으나, 지금은 대회가 아닌 개인 공부 시간이기 때문에 이 정도 시간은 충분히 할애해도 된다고 본다.



MyDiary.dat

iDailyDiary.lck

MyDiary.idx

MyDiary.blb





완성 된 다이얼로그 


여기에 비밀번호 sangsu를 입력해두었다. 

그렇다면 실제 MyDiary의 패스워드와 sangsu를 비교하는 구문이 존재할 것이다. 


여기서 패스워드가 틀리게 되면 Access Denied로 이동하게 되는데 Access Denied에 도달하기 전에 적절한 곳에 break point를 걸면 무사히 루틴 비교 구문을 들여다 볼 수 있다.





이런식으로 코딩 되어있는 것이다.




그 다음 내가 입력한 패스워드와 실제 패스워드를 비교하는 구문이 나온다. 


근데 의아하게 비교 루틴이 전혀 없다 ! 


win32api 분석 꼬이지만 않았다면, 좀 더 빠르게 풀 수 있었을 것이다 .  

키 값은 공개 하지 않겠다. 

끝 



'0x02 Reverse Engineer > 0x03. Etc' 카테고리의 다른 글

ROOTME ELF PTRACE  (0) 2018.05.19
ROOTME FAKE INSTRUCTION  (0) 2018.05.19
KISA Diary 문제풀이 및 상세분석  (0) 2018.05.18
Rootme ch25 C++ Basic  (0) 2018.05.03
Simple Crack Me Writeup  (0) 2018.04.28
BruteForce is Wonderful!  (0) 2018.04.02
0 Comments
댓글쓰기 폼