인프런 - 윈도우 악성코드(malware) 분석 입문 과정 섹션 0의 1.6 ~ 1.8 강의와 섹션 1 강의를 수강하였다.
▶ 섹션 0 - 1.6 ~ 1.8
1. 올리디버거
- 올리 유스척이 개발한 x86 디버거
1.1. CPU 인터페이스
- 디스어셈블러 : 어셈블리어를 볼 수 있다.
- 레지스터 : 레지스터의 내용을 볼 수 있다.
- 덤프 윈도우 : 메모리에 저장된 값을 볼 수 있다.
- 스택 : 스택의 상태를 볼 수 있다.
1.2. 메모리 맵
- 프로그램의 배열 상태를 확인할 수 있다.
1.3. 스레드
- View → Threads를 통해 현재 실행 스레드를 확인할 수 있다.
- 각 스레드는 개별 스택을 가지고 있다.
2. 올리디버거 사용 방법
2.1. 올리디버거 기본 단축키
실행(Run/Play) | Debug → Run | F9 |
정지(Pause) | Debug → Pause | F12 |
선택까지 실행 | Breakpoint → Run to Selection | F4 |
리턴까지 실행 | Debug → Execute till Return | Ctrl + F9 |
사용자 코드 전까지 실행 | Debug → Execute till User Code | Alt + F9 |
싱글 스텝 / 스텝 인투 | Debug → Step Into | F7 |
스텝 오버 | Debug → Step Over | F8 |
함수 따라가기 | Enter | |
뒤로 가기 | - |
2.2. 브레이크 포인트 단축키
소프트웨어 브레이크 포인트 | Breakpoint → Toggle | F2 |
조건 브레이크 포인트 | Breakpoint → Conditional | Shift + F2 |
하드웨어 브레이크 포인트 | Breakpoint → Hardware, on Execution | |
접근(읽기, 쓰기, 실행)에 대한 | ||
메모리 브레이트 포인트 | Breakpoint → Memory, on Access | F2(메모리 선택) |
쓰기에 대한 메모리 브레이크 포인트 | Breakpoint → Memory, on Write |
3. 레나튜토리얼 1번 분석 및 해결 방법
- 올리디버거에서 reverseMe.exe 파일을 실행한다.
- 라이센스를 새로 구입하라는 팝업창이 뜨면서, 프로그램이 종료되는 것을 확인할 수 있다.
- 가장 먼저, Keyfile.dat 파일이 존재하는지 확인한다.
- Keyfile.dat 파일이 없으면, 라이센스를 새로 구입하라는 팝업창을 출력한다.
- Keyfile.dat 파일이 존재하면 Keyfile.dat 파일을 읽어온 뒤, 다음 코드를 실행한다.
- 메모장을 이용해 Keyfile.dat 파일을 생성한다.
- 이때, 프로그램에서 keyfile.dat 파일의 내용을 읽어오므로 임의 값 aaaaa를 넣어준다.
- 그리고, reverseMe.exe와 같은 경로에 해당 파일을 저장한다.
- reverseMe.exe를 다시 실행해보면 팝업 문구가 달라진 것을 확인할 수 있다.
- Keyfile.dat 파일의 내용이 올바르지 않다는 내용이 출력된다.
- Keyfile.dat 파일을 정상적으로 읽으면, [402173] 주소에 저장된 값과 16진수 10을 비교한다.
- [402173] 주소에 5가 저장 되어있는 것을 확인할 수 있다.
- 새로 생성한 Keyfile.dat 파일에 a 5개를 저장했으므로 5가 저장된다.
- 즉, [402173] 주소에는 Keyfile.dat 파일에서 읽어온 문자의 개수를 저장한다.
- 그러나, [402173] 주소에 저장된 값과 16진수 10의 값이 달라 [004010F7] 주소로 점프하게 된다.
- 그러므로, Keyfile.dat 파일에 a 16개를 넣어준다. (16진수 10 = 10진수 16)
- 프로그램을 다시 실행하고, [402173] 주소에 저장된 값을 확인해보면 10이 저장되어 있다.
- Keyfile.dat 파일에 저장된 문자열 개수가 16개 이상인 경우, [EAX+40211A] 주소에 저장된 값을 AL에 저장한다.
- [40211A] 주소에 저장된 값을 확인해보니 Keyfile.dat의 내용이 저장되어 있다.
- 프로그램을 실행하면 Keyfile.dat 파일의 내용이 올바르지 않다는 내용이 출력된다.
- 다시 어셈블리를 해석해보면, EBX에는 Keyfile.dat 파일에 저장된 문자열에 접근하기 위한 인덱스 번호가 저장되고, ESI에는 Keyfile.dat 파일에 문자 G가 몇 개 저장되었는지 확인한다.
- 즉, 반복문을 통해 Keyfile.dat 파일의 내용을 읽고, G의 개수가 몇 개인지 검사한다.
- 따라서 Keyfile.dat 파일에 G를 8개 포함하고, 최소 16글자 이상 저장해야한다.
- keyfile.dat에 G를 16개 저장한다.
- 반복문이 끝나면, ESI가 10이 되면서 [004010F7] 주소가 아닌 [00401205] 주소로 점프하게 된다.
- [00401205] 주소다.
- 해당 명령어들을 실행하면, 축하 메세지가 출력된다.
▶ 섹션 1. PE 파일과 패커
1. PE 파일 개요
1.1. Portable Executable File Format : 파일(File)이 이식 가능한 다른 곳에 옮겨져도(Portable) 실행 가능하도록 (Executable) 만든 포맷(Format)
- PE 포맷(위키피디아에서의 정의)
- 윈도우에서 사용하는 실행 파일, DLL 파일 등을 위한 파일 형식
- 윈도우 로더가 실행 가능한 코드를 관리하는데 필요한 정보를 캡슐화한 데이터 구 조체
- 링킹을 위한 동적 라이브러리 참조, API 익스포트와 임포트 테이블, 자원 관리 데이 터 그리고 TLS 데이터를 포함
1.2. 실행 파일 컴파일 과정
- C 코드 → 컴파일 → obj파일(시스템에서 인식 가능한 파일. 이 파일만으로는 호환 성을 제공하기 어려움) → 링킹 과정(링커) → exe 파일
- obj: 시스템에서 인식 가능한 파일, 호환성 제공 어려움, h에 대한 내용만 가지고 있음
- Link: 호환성을 연결해주기 위한 과정(Linking), DLL 리소스 데이터, Import, Export 테이블을 처리할 수 있는 정보를 윈도우에 약속된 규약 에 맞춰 파일 만듦
- exe: Linker가 만드는 파일을 다 합한 것
1.3. PE 파일 분석에 사용되는 도구
- PEview
- Stud_PE
- PEiD
- exeinfo
- pestudio
- preframe.py
2. PE 파일 구조 이해
2.1. PE 파일 구조 주요 구조
- IMAGE_DOS_HEADER
- IMAGE_NT_HEADER
- IMAGE_FILE_HEADER
- IMAGE_OPTIONAL_HEADER
- IMAGE_SECTION_HEADER
- IMAGE_IMPORT_DESCRIPTOR
- IMAGE_EXPORT_DIRECTORY
- IMAGE_IMPORT_BY_NAME
- IMAGE_THUNK_DATA32
- IMAGE_DOS_HEADER
- DOS 에서도 실행가능하도록 호환성을 제공하기 위한 헤더
- MZ 헤더의 유무를 통해 바이너리가 PE 파일인지 검사
- e_lfanew : MZ 헤더의 끝부분에 4바이트로 존재. PE 헤더의 위치를 알려주므로 중요.
- IMAGE_NT_HEADER 1
- Signature : PE|0|0, 4바잍, 바이러스에 자신의 시그니쳐를 심기도 함, 바이러스나 악성코드 감염 표식용으로 사용(지금은 x)
- IMAGE_NT_HEADER 2
- 나머지 두 개의 큰 구조체로 이루어짐
- FileHeader, OptionalHeader
- IMAGE_FILE_HEADER : WORD Machine(어떤 cpu에서 실행 가능한지 알림), WORD NumberOfsections(이 파일이 가진 세션의 개수를 알림, 일반적으로는 4개의 섹션이 존재), DWORD TimeDateStamp(obj→EXE 파일을 만든 시간을 알림), WORD SizeOfOptionalHeader(IMAGE_OPTIONAL_HEADER32의 구조체 크기를 알림), WORD Charcteristics(이 파일이 어떤 형식인지 알림)
- IMAGE_NT_HEADER 3
- IMAGE_OPTIONAL_HEADER : Standard Fields
- IMAGE_FILE_HEADER
- Machine : 어떤 CPU에서 실행 가능한지 알림
- NumberOfSections : 이 파일이 가진 섹션의 개수를 알림
- TimeDataStamp : obj → EXE 파일을 만든 시간 알림
- SizeOfOptionalHeader : optional 헤더의 크기를 알림( PE를 로딩하 기 위한 굉장히 중요한 구조체를 담고 있음. 운영체제마다 크기가 다를 수 있어서 PE로더에서는 이 값을 먼저 확인)
- Characteristics : 파일이 어떤 형식인지 알림
- IMAGE_OPTIONAL_HEADER
- Magic : 32비트인지 64비트인지 알려줌
- MajorLinkerVersion , MinorLinkerVaersion : 사용한 컴파일러 버전을 알려줌
- SizeOfCode : 코드 양의 전체 크기
- 악성코드 : 이 값을 참고하여 자신의 코드를 복제할 위치 기준을 잡음
- 솔루션 : 코드 섹션의 무결성 검사
- AddressOfEntryPoint : 파일이 메모리에서 시작되는 지점
- BaseOfCode : 실행 코드 위치
- ImageBase와 BaseofCode를 더한 값부터 코드 시작.
- ImageBase : 로드할 가상 메모리 주소
- SectionAlignment, FileAlignment : 각 세션을 정렬하기 위한 정렬 단위(기본값 0x1000)
- SizeOfImage: EXE,DLL이 메모리에 로딩됐을 때 전체크기
- SizeOfHeaders : PE 헤더의 크기를 알림(기본값 0x1000)
- IMAGE_DATA_DIRECTORY
- VirtualAddress Size 필드, Export, Import, Rsrc 디렉터리와 IAT 등의 가상 주소와 크기 정보를 가짐.
- 16가지의 데이터 디렉터리에 대한 정보를 가지고 있다.
- 섹션(Section)
- PE 파일에서 섹션은 프로그램의 실제 내용을 담고 있는 블록
- PE가 가상 주소 공간에 로드된 후 섹션 내용이 참고되고 실행
- IMAGE_SECTION_HEADER
- 주로 각 세션에 대한 이름, 시작 주소, 사이즈 등의 정보를 관리하는 구조체
- IAT 호출 구조
2.2. PE 헤더 복구하기
- 1번 notepad
- 파일 실행이 안됨 → 원래 파일과 구조가 다름 → 정상적인 파일은 MZ로 시작
- 하지만 1번 파일은 Boan Project….가 있음. 이를 제거하면 해결 가능
- 2번 notepad 문제
- Analysis > File-compare > compare 들어가서 2번 문제 파일과 원래 파일 선택 후 다른 부분을 찾아서 바꿔준다.
- Analysis > File-compare > Next difference 들어가면 다음으로 차이가 나는 부분을 찾을 수 있다.
- 이를 원래 파일과 똑같이 변경해주면 해결 가능
3. 패커 개요
3.1. 패커(Packer)
- 실행 파일 압축기, 실행 파일 패킹
- 사용 목적
- (과거) PE 파일 크기 줄이고자하는 목적
- (현재) PE 파일 내부 코드와 리소스(string, API 등)를 감추기 위한 목적
- 패커의 흐름
- A 패킹 후 B의 압축이 됨 → C는 압축을 해제해 줌 → 실행 -패킹하기 전 상태는 메모리 상태와 같다.
- 메모리 내 파일 패킹 구조
3.2. 백신 우회 방법
- 시그니처 변경
- 단순히 변수 및 개를 추가 및 함수 위치를 변경하여 리빌드
- 쓰레기 코드를 통한 우회 방법
- 네 줄이 수행된 경과를 보면 아무것도 것이 없음 (대칭 구조)
- 헤더 변조
- TimeDataStamp, Optional Header의 CheckSum, 메모리 속성 변조
3.3. Themida
- 지상 최고의 패커라 불림
- 안티 디버깅과 안티 분석, 언패킹 분석을 매우 어렵게 하는 안전한 패커
- VMware, 디버거, 프로세스 모니터 분석을 방지하는 기능
- 패킹된 실행 파일은 이례적으로 크기가 큼
- 언패커가 존재하나 Themida 버전과 프로그램을 패킹할 때 사용한 설정에 따라 성공률이 다름
4. UPX 언패킹
4.1. 패킹
- 원본 파일 자체를 변경
- (바탕화면에서) start > Command Prompt(run(Window + R) > cmd 입력) > (Commad Prompt 창에서 입력) cd Desktop > upx.exe ori_notepad.exe > 압축이 됨
- 언패킹
- upx.exe ori_notepad.exe 사이의 -d 옵션을 입력하면 됨
- → upx.exe -d ori_notepad.exe
- 원본 파일 건들이지 않고 패킹 (새로운 파일 만들어서 패킹)
- upx.exe ori_notepad.exe -o ori_notepad_upx.exe 입력하여 패킹
- ori_notepad.exe와 ori_notepad_upx.exe 비교
- *PEview.exe로 두 파일 열기
- *구조가 바뀐 것을 확인할 수 있다.
- SECTION.text, SECTION.data → SECTION UPX0, SECTION UPX1
- 검정색 네모 박스에서 바뀐 부분 확인할 수 있다.
- IMAGE_NT_HEADERS > Signature, IMAGE_FILE_HEADERS 그대로유지
- IMAGE_OPTIONAL_HEADERS
- 검정색 선 아래부터 Data 값이 변경된 것을 확인할 수 있다.
- IMAGE_SECTION_HEADERS ~
- 전체적인 사이즈와 권한이 변경되었고 ori_notepad_upx.exe에는 80000000 IMAGE_SCN_MEM_WRITE 이 새로생겼다.
- 실제 파일 사이즈는 없고 가상 사이즈를 설정하여 입력을 받고 나중에 입력 받은 내용을 실행
4.2. UPX 언패킹
- *패킹이 된 파일은 잘 분석이 안되기 때문에 열기 전 사전에 진짜로 패킹된 파일을 열려고 하는 건지 물어봄
- *BP 걸거나 주석 달아도 나중에 다 날아감 → 언패킹하면 원래 파일에 메모리에 의 해서 작성한 메모리가 날아감
- OllyDbg로 ori_notepad_upx.exe 열기
- PUSHAD
- EAX ~ EDI까지 데이터를 싹 다 넣음
- 레지스터에 잠깐 보관하고 언패킹을 하고 레지스터 복구해서 정상적으로 프로그램을 실행하기 위해서 사용한다(+POPAD)
- 언패킹
- Debug > Animate over
- 수동 언패킹 with Lena 21
- 문제 풀기 전
- UnPackme_UPX.exe 바탕화면에 옮기기
- 필요한 파일 다운로드
- 인터넷 > import rec 검색 > [Tool] ImportREC v1.7 Final ~ 클릭 > ImportREC 1.7c.rar 다운로드 > 압축 풀고 사용
- 문제 풀기
- PUSHAD F8로 실행
- 덤프 창에 esp 검색 > 맨 앞 숫자에 마우스 오른쪽 클릭 Breakpoint > Hardware, on access (메모리에 접근할 때 BP를 걸겠다) > Byte (한 바이 트 BP 검)
- BP 확인 방법: Debug > Hardware breakpoints
- POPAD 끝난 이후
- JMP 해서 원본 프로그램 실행
- Piugins > OllyDump > Dump debugged process → Rebuild import 체크 해제 > Dump > Unpackme_UPX_dump.exe 저장
- ImportREC
- OllyDbg 종료하면 안됨 → 해당 import 내용을 Unpackme_UPX_dump.exe에 적용을 해줬기 때문에 종료하면 적용되지 않음
- ImportREC 실행
- unpackme_upx.exe 선택 > OEP 00001000 변경 후 AutoSearch, Size 00001000 변경 후 Get Imports > Fix Dump (Import 내용 dump에 적용할 때 클릭) > UnPackme_UPX_dump.exe 선택 후 OPEN 클릭
'4-3. 2023-2 심화 스터디 > 윈도우 악성코드 분석' 카테고리의 다른 글
[2023.11.11] 인프런 윈도우 악성코드(malware) 분석 입문 과정 강의 수강 - 섹션 4 (1) | 2023.11.17 |
---|---|
[2023.11.04] 인프런 윈도우 악성코드(malware) 분석 입문 과정 강의 수강 - 섹션 3 (0) | 2023.11.10 |
[2023.10.14] 인프런 윈도우 악성코드(malware) 분석 입문 과정 강의 수강 - 섹션 2 (1) | 2023.10.14 |
[2023.09.23] 인프런 윈도우 악성코드(malware) 분석 입문 과정 강의 수강 - 섹션 0의 1.1~1.5 (0) | 2023.09.28 |