4.4.1 IDA 활용한 분석 개요
*IDA: 대중적인 디버거
*목표: 5-1 샘플 이용하여 IDA의 전체적인 흐름 파악 및 익숙해지기
1. IDA 기본
- 헥스레이(Hex-Rays)사에서 배포
- PE(Portable Executable), COFF(Common Object File Fromat, 유닉스 공용 라이브러리 포맷), ELF(Executable and Linking Format, 유닉스용 실행 파일 포맷 지원)
- x86, x64 지원
- 함수 발견, 스택 분석, 지역 변수 확인 등 많은 기능 제공
- 과정의 모든 부분 수정, 재배치, 재정의
- 분석 진행 상황 저장 기능(주석 작성, 레벨링, 함수 이름 붙이기)
- 막강한 플로그인 지원
2. IDA 활용
1) 파일 올리기
2) 디스어셈블리 윈도우 모드 (스페이스 바 키로 전환 가능)
텍스트 모드 | 그래프 모드 |
첫 번째 박스: 주소(섹션명: 가상메모리 주소) 두 번째 박스: 디스어셈블리 된 어셈블리어 ; 주석 |
어셈블리어를 위한 프로그램 흐름 |
기존 보기 방식 | 그래프 형태로 출력 |
메모리 주소, 옵코드, 섹션 명 등을 출력 | 화살표 색깔과 방향을 이용 -> 분석 도중 프로그램의 흐름 파악 |
실선: 무조건 점프, 점선: 조건 점프 | 빨강: 조건 점프가 거짓인 경우 초록: 조건 점프가 참인 경우 파랑: 무조건 점프인 경우 |
3) Tuto Comments (Options > General)
4) 분석에 유용한 윈도우
윈도우 | 설명 |
함수 윈도우 (Function Window) | 실행 파일 내의 모든 함수 목록화 |
이름 윈도우 (Names Window) | 함수, 명명된 코드, 명명된 데이터와 문자열 포함한 이름 관련 모든 주소 목록화 |
문자열 윈도우 (Strings Window) | 5자 이상의 ASCII 문자열 출력 (문자열 윈도우의 Setup에서 설정 변경 가능) |
임포트 윈도우 (Imports WIndow) | 임포트 되는 모든 함수 목록 |
익스포트 윈도우 (Exports Window) | 익스포트 되는 모든 함수 목록 |
구조체 윈도우 (Structures Window) | 데이터 구조 레이아웃 목록 |
5) 원래 보기로 되돌리기 (Windows > Reset Desktop)
6) IDA Pro 특징 - 주소 명칭
Sub | 함수 시작 링크 형식: sub_주소 함수 참조하는 내용에서 사용 |
Loc | 목적지로 점프하는 링크 형식: roc_주소 jmp, jz, jnz 등 점프 관련 명령어들에 사용 |
Offset | 메모리 내의 오프셋 링크 형식: offset 캡션/텍스트/주소 주소에 있는 데이터를 가지고 옴 캡션/텍스트를 가리키는 데이터를 넣음 |
7) 검색
(1) Search > Next Code: 저장한 명령어를 담고 있는 다음 위치로 커서 이동
(2) Search > Text: 전체 디스어셈블리 윈도우에서 특정 문자열 검색
(3) Search > Sequence of Bytes: 특정 바이트 순서로 16진수로 보기 윈도우에 있는 바이너리 검색
(4) 메뉴바 검색창: 클릭하고 바로 검색 가능
8) xref 상호 참조
- 함수를 호출한 위치나 사용한 문자열 위치 알림
- 함수의 호출된 파라미터로 신속히 이동
*지역 변수와 파라미터 분리 가능
9) 그래프 옵션
번호 | 기능 |
1 | 현재 함수의 플로우 차트 작성 |
2 | 전체 프로그램의 그래프 함수 호출 |
3 | 현재 선택한 상호 참조를 알아낼 수 있게 상호 참조 그래프 작성 |
4 | 현재 선택한 심볼에서 상호 참조 그래프 작성 |
5 | 사용자가 정의한 상호 참조 그래프 작성 |
10) 함수 이름 변경
11) 기타
- 주석: 세미콜론(;) 활용하여 주석 추가, 자동 주석 추가 가능
- 원하는 특징 표준 심볼 상수가 보이지 않을 경우: View > Open Subviews > Type Libraries 사용하여 수동으로 로딩
4.1.2 IDA 활용한 실습 첫 번째
1. *DllMain의 주소는 무엇인가?
*DllMain
- DLL의 메임 함수; DLL이 로드 될 때 실행되는 필수적인 함수
- 나머지 구체적인 부분은 구글에 MSDN DllMain 검색
그래프 모드에서 DllMain 확인
스페이스 바 키를 눌러 텍스므 모드로 전환하여 주소 확인
DllMain 주소: 1000D02E
Names를 클릭하여 나오는 창에서 dllmain을 입력 -> 사진처럼 주소 확인
주소: 1000D02E
=> 답: 1000D02E
2. Imports 윈도우를 이용해 gethostbyname을 탐색해보자. 임포트 위치는 어디인가?
(Imports 창 들어가서 Name 클릭하여 정렬하는 것으로 찾기 가능)
창의 아무 곳이나 눌러 gethostbyname을 입력하면 (입력하기도 전에) gethostbyname의 임포트 위치 확인 가능
임포트 위치: 0x100163CC
⇒ 답: 0x100163CC
3. gethostbyname을 CALL 명령어는 몇 개인가?
문제 2에서 찾은 gethostname 임포트 주소를 더블 클릭 -> 임포트 어드레스로 이동
XREF 클릭 > 마우스 오른쪽 클릭 > Jump to cross reference... (Ctrl+X 단축키 사용해도 무방)
어디서 이곳으로 참조를 해서 점프를 하는가를 찾을 수 있음 -> CALL 함수
총 9개의 CALL을 확인할 수 있다.
⇒ 답: 9개
4. 0x10001757에 위치한 *gethostbyname 호출을 보면 어떤 DNS 요청이 이뤄지는지 알 수 있는가?
*gethostname?
-이름을 넣어주면 호스트데이터베이스가 호스트 이름과 관련된 정보를 반환해 줌, IP 검색할 때 많이 사용함
→ 어떤 요청이 있는지 확인하기 위해서 gethostname의 전달되는 name 인자를 확인하면 된다.
IDA View-A에서 g를 누르고 나오는 창에 010001757을 입력 > OK 클릭
gethostname이 있는 곳으로 바로 이동
보통은 그 위에 name이 전달되고 있음
일반적인 경우 name이 바로 찍혀있 즉, string이 바로 찍혀있음
분석하면 eax은 10019040에서 데이터를 가져 온 후 eax에 0Dh를 더함
그래프 모드 창에서 g를 눌러 10019040을 입력 -> 정확하게 보기 위해 Hex View-A로 확인
→ 0x10011994에서 데이터를 가지고 와서 0D를 더해줌
0x10019194 + 0D = 100191A1
100191A1을 검색
5B부터 시작하여 5D까지 Dbyte만큼 이동
-> 실질적으로 원하는 데이터는 5D 다음부터 박스가 끝날 때까지
⇒ 답: pics.practicalmalwareanalysis.com
5-6. 0x10001656에 있는 서브루틴에서 IDA Pro는 지역 변수 몇 개를 인지하고 있는가? 0x10001656에 있는 서브루틴에서 IDA Pro는 파라미터 몇 개를 인지하고 있는가?
전과 같은 방식으로 10001656을 검색하고 이동
⇒ 5번, 6번 답: 20개의 지역변수, 1개의 파라미터 가짐
7. Strings 윈도우를 이용해 디스어셈블리 내의 문자열 \cmd.exe /c를 찾아보자. 어디에 있는가?
위에 검색창 이용 -> \\\\cmd.exe /c 입력 -> 주소 찾음
주소: 0x100101D0
*위에 검색창에 검색하고자 하는 것을 입력할 때 오타가 나면 싹 지워지고 단어 하나마다 검색을 진행하는 것 같으므 시간이 오래 걸 릴 수도 있음
⇒ 답: 0x100101D0
8. \cmd.exe /c를 참조하는 코드 영역에서 무슨 일이 발생하는가?
*cmd.exe /c를 실행하면 실행이 끝날 때까지 포롬프터로 돌아오지 않음
어떤 시스템에 대한 정보를 획득한 후 cmd또는 commadn 실행
즉, 버전에 따라서 cmd.exe를 실행할 지 command.exe를 실행할 지 루틴을 정함
환경을 탐색하고 정한 다음 백도어로서의 역할을 하기 위해 들어온 명령어를 따라서 루틴 가르기 시작
*사람마다 다르게 해석할 수 있음
=> 답: 코드 영역에서는 공격자의 실행 명령어를 실행하기 위한 세팅 작업이 일어난다.
9. 같은 영역 0x1001018에서 dword_1008E5C4는 경로를 지정하는 전역 변수로 보인다. 악성코드는 어떻게 dword_1008E5C4fmf 설정하는가? (힌트: dword_1008E5C4의 상호 참조를 이용하라)
이전 실습과 마찬가지로 g를 눌러 100101C8를 검색하여 찾음
ebx라는 데이터를 가져와서 dword_1008E5C4에 넣고 있음
dword_1008E5C4를 더블 클릭 -> Ctrl+X를 눌러 문제 3처럼 참조하는 것 확인
10001656+22를 클릭한 상태에서 OK를 누름
세팅되는 구간을 찾을 수 있음
GetVersionExA를 통해 dword_1008E5C4에 데이터 넣음
이것을 위에서 봤던 100101C8에서 비교 -> 어디 루틴으로 갈 지 정함
답: GetVersion이라는 함수를 통해서 커널버전을 저장한다.
4.1.3 IDA 활용한 실습 두 번 째
10. 0x1000FF58에서 서브루틴으로 수백 라인은 문자열을 비교하기 위한 일련의 memcmp 비교다. robotwork와 문자열 비교가 성공적으로 이뤄지면 무슨 일이 일어나는가? (memcmp가 0으로 반환)
검색창에서 robotwork를 검색 -> 그래프 모드에서 찾음
맞다는 가정하고 빨간색 선을 따라감
robotwork가 실행됐을 때 call sub_100052A2가 실행됨
마우스 오른쪽 클릭 > Rname (N) > sub_100052A2 → MyRobotwork 변경
MyRobotwork 분석
레지스트리를 오픈하고 있는데 Microsoft에 CurrentVersion을 오픈하고 있음
WorkTime과 관련된 것을 레지스트리쿼리를 하고 있
*atoi: WorkTime을 ASCII 값을 받아서 int 형으로 바꿈
문자열을 *sprintF를 한다. *sprintF: 문자를 붙이는 역할
→ rovot이 작동하는 시간에 대해서 출력해주는 문구가 적혀있다.
⇒ 레즈스트리를 조회해서 send하는 (어떤 문자열을 만들어서 send하는) 기능을 가지고 있음
빨간색 동그라미(Display graph of xrefs specified by the user)친 그래프 기능을 클릭하고
바로 OK 버튼을 눌러 그래프를 만듦
함수를 대략적으로 파악할 수 있
⇒ 답: robotwork는 시간을 출력하는 것으로 보임. 나중에 문자열도 만들고 network를 통해 데이터를 전송
11. PSLIST 익스포트는 무슨 역할을 하는가?
Exports 창에 들어가서 PSLIST를 찾을 수 있음
무슨 역할을 하는지 단번에 파악하기 위해서 상호 참조 그래프를 이용
10번 문제에서와 같이 그래프 모양을 클릭
naver에 함수들의 이름을 검색하여 해당 함수를 파악
→ 프로세스를 리스팅하는 함수이다.
왼쪽 루틴은 데이터를 자신이 스스로 확인해보는 것이고
오른쪽 루틴은 데이터를 볼 때 소켓을 통해서 통신을 할 때 사용
⇒ 답: 프로세스 리스트를 분석하는 함수이다.
12. 그래프 모드를 이용해 sub_10004E79 상호 참조 그래프를 그려보자. 이 함수에 진입하기 위해 호출하는 API 함수는 무엇인가? 해당 API 함수에만 기반을 두고 이 함수를 어떤 이름으로 변경하겠는가?
GetSystemDefaultLangID를 얻어서 데이터를 보내는 것
StartAddress 함수는 IDA의 특징이며 스레드를 실행시킬 때 나오는 명령어
Names 창에 가서 StartAddress 검색하고 더블 클릭해서 그래프 모드로 봄
가장 위에 있는 곳에서 StartAddress를 클릭한 후 Ctrl+X를 눌러 프로세스 레퍼런스에 들어감
StartAddress를 클릭해서 바로 CreateThread하는 부분이 나옴
→ CreateThread를 통해서 만들어짐
⇒ 답: CreateThread를 통해서 백도어 함수를 진행한다, 랭기지 ID 체크 함수인 듯하다.
13. DllMain이 직접 호출하는 윈도우 API 함수는 몇 개인가? 두 번째 깊이(depth of 2)에서 몇 개인가?
형광펜한 부분을 바꿔주면 설정한 곳부터 호출
DllMain에서 호출하는 2개까지의 깊이에서만 구하면 됨 (나머지는 점점점으로 표시)
2~30개 일 것으로 보임
⇒답: 너무 많다(굉장히 찾기 힘듦), 2~30개일 것으로 추정
14. 0x10001358에서 Sleep 호출이 존재한다. (sleep까지 수밀리초 값을 파라미터로 갖는 API 함수) 코드 후반부를 보면 이 코드가 수행되려면 프로그램이 얼마 동안 Sleep하는가?
Sleep 함수: 잠을 자는 함수 (일반적으로 인자를 하나만 받음)
Sleep 함수에 dwMilliseconds가 전달되면 milliseconds만큼 쉬겠다는 것을 의미
eax에 얼마가 넘어가느냐에 따라서 데이터가 갈림 (10019020에서 넘어옴)
→ 10019020으로부터 데이터를 가져와 OD를 더하고 여기에 있는 아스키 값을 인트형으로 바꾸고 3E8을 곱한다.
10019020으로부터 데이터: 0x100192AC
형관펜으로 표시된 부분을 지나고 30에 걸림 -> OD를 더하고 여기에 있는 아스키 값(”30”)
인트(30)형으로 바꾸고 3E8(1000)을 곱함
→ 30 * 1000 밀리세컨즈 = 30초
⇒ 답: 30초
15-16. 0x1001701에서 소켓을 호출한다. 세 가지 파라미터는 무엇인가? 소켓과 IDA Pro에서 명명한 심볼 상수 기능을 이용해 이 파라미터를 좀 더 유용하게 할 수 있겠는가? 변경 후 파라미터는 무엇인가?
*이전 문제들과 동일하게 g 단축키로 나온 창에 1001701을 검색 -> 그래프 모드 확인
socket으로 전달되는 데이터가 어디로 오는지 확인해야 함
마우스 오른쪽 클릭 > Use standard symbollic constant > 2 → AF_INET 변경
나머지 push 값들도 변경 (위 오른쪽 사진)
⇒15-16번 문제 답: 6 1 2, 변경 후 파라미터 IPPROTO_TCP SOCK_STREAM,AF_INET
플러그인 IDA 파이썬 스크립트 1001D988
*상용프로그램에는 IDA 파이썬이 깔려있음, 우리 프로그램에는 안 깔려 있음 → 개념만 설명
50byte 정도가 암호화된 문자열
Notepad를 이용하여 Lab05-01.py 파일을 확인
→ 0x55 XOR시킨 후 그 바이트로 패치
*IDA 파이썬을 설치하고 메뉴를 통해 오픈을 하고 파이썬 스크립트를 클릭해주면 바로 실행이 되어서 다 바뀜
'4-3. 2023-2 심화 스터디 > 윈도우 악성코드 분석' 카테고리의 다른 글
[2023.11.11] 인프런 윈도우 악성코드(malware) 분석 입문 과정 강의 수강 - 섹션 4 (1) | 2023.11.17 |
---|---|
[2023.10.14] 인프런 윈도우 악성코드(malware) 분석 입문 과정 강의 수강 - 섹션 2 (1) | 2023.10.14 |
[2023.10.07] 인프런 윈도우 악성코드(malware) 분석 입문 과정 강의 수강 - 섹션 0, 섹션 1 (1) | 2023.10.09 |
[2023.09.23] 인프런 윈도우 악성코드(malware) 분석 입문 과정 강의 수강 - 섹션 0의 1.1~1.5 (0) | 2023.09.28 |