- [Forensics] 물리 메모리 포렌식의 이해 + Volatility2024년 08월 02일 00시 13분 33초에 업로드 된 글입니다.작성자: 방세연
메모리 포렌식의 목적
: 프로세스의 행위 탐지, 네트워크 연결 정보, 사용자 행위, 복호화, 언패킹, 디코딩된 데이터, 패스워드와 암호 키 획득
가상 메모리 공간은 운영체제에서 매우 중요한 개념임
메모리 포렌식의 대상
: 물리 메모리, 페이지 파일, 하이버네이션 파일
http://www.porcupine.org/forensics/forensic-discovery/chapter8.html
가상 메모리 공간에 대한 이해
가상 메모리의 존재 이유 :
RAM은 한정된 영역이다. ( 4GB, 8GB, 16GB )
가상 메모리는 메모리 의존성을 없애고, 관리적 측면의 높은 추상성을 제공한다.
( => ⭐보안 : 가상 메모리가 '접근 제어'를 수행한다는 점이 가장 중요하다. )
관리의 최소단위 : 1byte ( 각 바이트에는 주소가 붙는다. )
주소의 길이 - OS, CPU ...가 몇 bit인지에 따라 결정된다.
동적 주소 변환 ( Runtime ) :
프로세스가 실행 중인 중간에 주소 체계를 변환한다. ( Segemantation )
사용자 영역과 커널 영역
Win32 시스템의 모든 프로세스는 4GB의 연속된 공간 사용 (32 bit)
User Mode :
0x00000000 ~ 0x7FFFFFFF
일반 애플리케이션 실행 모드로 실행되며, 제한된 권한만을 부여받는다.
( 시스템 자원/ 하드웨어과 직접적으로 상호작용할 수 없다.
즉 메모리, I/O 포트, CPU 제어 레지스터에 직접 접근할 수 없다. )
User Mode의 가상 메모리 주소 공간 -
각 프로세스는 자신만의 독립된 가상 메모리 공간을 가지고 있다.
다른 프로세스의 메모리 공간에는 접근할 수 없다. 각각의 메모리 공간은 메모리 보호를 제공한다.
System Call -
System Call을 통해 시스템을 호출하여 Kerner에 요청하면 시스템 자원에 접근할 수 있다.
( 파일 입출력, 프로세스 생성, 네트워크 통신 등의 작업이 간접적으로 호출을 통해 이루어짐 )
x86 주소공간의 User Mode는
64 kb 보호 영역, 프로세스 헤드, 스레드 스택, PE 이미지, PEB ... 등으로 이루어져 있다.
Kerner Mode :
0x80000000 ~ 0xFFFFFFFF
메모리 관리자(Memory Manage) 가 위치 -> [ RAM + Swap 영역 ]
모든 하드웨어 자원에 대한 완전한 접근 권한 소유, 시스템 핵심 기능 관리 및 제어
( 보안 ) 커널의 메모리 보호 -
메모리 보호 기능을 통해 User Mode의 프로세스가 다른 프로세스나 커널의 메모리에 접근하지 못하게 한다.
시스템 자원 관리 -
프로세스 관리, 메모리 관리, 파일 시스템 관리, 장치 드라이버 관리 등의 기능 수행
x86 주소 공간과 x64 주소 공간
각 프로세스는 상대방의 프로세스에 접근할 수 없다.
(process A, process B, process C ...)
가상 주소를 물리 주소로 변환하는 과정
가상주소 (가상메모리) -
실제 위치에 상관없이 0번지부터 시작하는 연속 메모리 공간
실제 위치하는 공간은 물리주소 또는 swap 영역
프로세스가 바라보는 메모리 영역
물리주소 (물리 메모리) -
메모리 관리자가 바라보는 메모리 영역
동적 주소 변환
가상 주소를 실제 메모리의 물리 주소로 변환
=> 프로세스가 아무 제약 없이 사용자 데이터를 물리 메모리에 배치할 수 있다.
( swap 영역 : 물리 메모리가 부족한 경우에 배치되는 공간이다.)
메모리 분할 방식
고정분할방식
(페이징 기법)
고정분할방식 :
물리적 메모리를 정해진 개수만큼 영구적인 분할로 나눈다.
각 분할에 하나의 프로세스를 적재한다.
단점 : 외부조각 문제와 내부조각 문제, 프로그램 수 고정, 프로그램 최대 크기 제한
페이징 :
가상주소 : VA = <P, D> / 물리주소 : PA = <F, D>
(D = 프레임/페이지의 처음 위치에서 해당 주소까지의 거리)
물리주소 공간을 같은 크기로 나눠 사용한다.
분할된 가상 주소 각 영역은 "페이지", 물리 주소 각 영역은 "프레임"이다.
페이지는 어떤 프레임에도 배치될 수 있다. ( 페이지 크기 == 프레임 크기 ) (invalid = swap space)
페이지 테이블 : 물리 메모리 중 운영체제 영역에 존재한다. 다수의 프로세스 존재.
페이지 테이블 매핑 방식 : 직접 매핑, 연관 매핑, 집합-연관 매핑, 역매핑
주소 변환 과정 : VA<P,D> -> PA<F,D>
프로세스가 30번지 내용 읽는 과정
(1). 30B의 가상주소 VA=<3,0>
(2). 페이지 테이블의 3번째 프레임 => 1
(3.) 물리주소 프레임 1 PA =<1, 0>가변분할방식
(세그먼테이션 기법)가변분할 :
메모리에 적재되는 프로그램 크기에 따라 분할 크기, 개수를 동적으로 변하게 함
프로그램의 크기를 '고려'해서 메모리를 할당, 기술적으로 관리
세그멘테이션 :
페이지 단위가 아닌 의미 단위 segment로 공간을 나눔
프로세스 내 코드와 데이터, 함수 단위 등으로 나눌 수 있음
가변분할 방식 :
최초적합 - 위쪽 or 아래쪽에서 홀을 찾으면 바로 할당
최적적합 - 프로세스의 크기 이상인 공간 중 가장 작은 홀에 할당
최악적합 - 프로세스의 크기와 가장 많이 차이가 나는 홀을 찾으면 할당
단점 : 외부 조각 문제 =>
해결방안 : 컴팩션 (가용 공간 확보) - 다른 프로세스들의 자리도 옮겨야 한다.
프로세스 A, B, C가 가변분할 방식을 적용받는 모습
출처 : https://examradar.com/multiprogramming-fixed-partition-multiprogramming-variable-partition-questions-answers/
프로세스의 크기에 따라 메모리 공간이 동적 할당되고 해제되는 모습을 확인할 수 있다.(세그먼테이션- 페이징 혼용 기법) 페이지드 세그멘테이션 -
공유, 보안을 segment로 나눈 후 물리 메모리는 페이지로 나누는 혼용 기법을 사용한다.내부 조각 문제 : 프로세스를 할당할 경우 남는 메모리 공간이 발생하는 문제
외부 조각 문제 : 프로세스를 할당할 경우 남는 메모리 공간이 없어지는 문제
* 가변 분할 방식은 메모리 공간이 상황에 따라 동적이므로 외부 조각 문제만 나타난다.
프로세스 생성 과정
프로세스 : CPU에 의해서 주기억 장치에 상주된 프로그램이 처리되는 것
프로세스의 상태 : 생성(new), 준비(ready), 대기(waiting), 실행(running), 종료(terminated)
프로세스 상태도
생성(new) 프로세스가 PCB를 가지고 있지만 OS로부터 승인받기 전 준비(ready) OS로부터 승인 받은 후 준비 큐에서 CPU 할당을 기다림 대기(waiting) 프로세스가 CPU를 할당받아 실행 실행(running) 프로세스가 입출력이나 이벤트 발생을 기다려야 해 CPU 사용 멈추고 기다림 종료(terminated) 프로세스 실행 종료 🪟Windows 운영 체제에서 새로운 프로세스를 생성하고 실행하는 과정
1. 실행 파일 실행
사용자가 실행 파일을 실행하면, 운영 체제는 해당 파일을 로드하기 시작함.
2. 서브시스템(POSIX, MS-DOS, Win32 등) 확인
운영 체제는 실행 파일이 어떤 서브시스템을 사용하는지 확인함.
( 예를 들어, Win32 서브시스템을 사용하는 프로그램은 Win32 API를 통해 실행 )
3. EPROCESS, KPROCESS, PEB, 초기 주소 공간 설정
운영 체제는 새로운 프로세스의 구조체를 생성함.
EPROCESS : 실행 중인 프로세스에 대한 커널 모드 구조체
KPROCESS : 커널 모드에서 사용되는 프로세스 정보
PEB : 프로세스 환경 블록, 사용자 모드 프로세스의 환경 정보를 저장
초기 주소 공간을 설정하고 프로세스에 필요한 메모리 할당을 수행
4. 기본 스레드 생성
운영 체제는 프로세스의 첫 번째 스레드를 생성함.
이 스레드는 프로세스의 실행 시작 지점을 담당함.
5. 윈도우 하위 시스템에 새로 생성된 프로세스와 스레드 알림
Windows 하위 시스템(예: Win32 서브시스템)은 새로운 프로세스와 스레드의 생성에 대해 알림을 받음.
(GUI 애플리케이션에서 중요한 사항)
6. 기본 스레드에 의해 프로세스 환경 설정과 스레드 자원 할당
기본 스레드는 프로세스 환경을 설정하고 스레드가 실행될 자원을 할당받음
( 스택 메모리 할당, 초기화 코드 실행 등이 포함 )
7. 새로운 프로세스와 스레드의 컨텍스트 내부 주소 공간 초기화 완료
운영 체제는 새로운 프로세스와 스레드의 주소 공간을 초기화.
실행 파일이 올바르게 로드되고, 필요한 모든 초기화가 완료되었음을 의미.
물리 메모리 분석
물리 메모리 분석 방법
초기 :
문자열 추출 - 특정 패턴의 문자열 검색 / 메일, 계정, 비밀번호, 메신저 대화 등 탐색
파일 카빙 - 그래픽 이미지, HTML, 레지스트리 등 파일 카빙 기법으로 파일 획득
현재 :
오브젝트 검색 (물리메모리 상의 오브젝트 찾기 위한 방법 사용)
<- 리스트 워킹
EPROCESS 프로세스 이름을 이용한 프로세스 탐색 기법
KPCR을 이용한 프로세스 탐색 기법
<- 패턴 매칭
프로세스 구조체의 패턴을 이용해 메모리 영역 전체를 검색
은닉 프로세스라도 동일한 프로세스 구조체를 가짐
프로세스 메모리 관련 실습과 유용한 내용들 :
https://github.com/Faran-17/Windows-Internals/tree/main/Processes%20and%20Jobs/Processes
물리 메모리 분석 도구
RedlineTM, Volatility, Responder Pro, Second Look® Linux Memory Analysis, Volafox, Volafunx
Volatility 관련 명령어 정리
Volatility 설치를 완료해주었다.
운영체제 식별
imageinfo
profile을 확인할 수 있는 명령어이다.
이미지 정보
kdbgscan
KDBG 구조체를 확인할 수 있게 해주는 명령어이다. ( 디버거 데이터 블럭의 헤더에 포함된 시그니처 )
kpcrscan
KPCR을 확인할 수 있게 해주는 명령어이다. ( 사용하고 있는 CPU의 정보를 담고 있는 구조체 )
프로세스 정보
pslist
시간 순서대로 프로세스를 검색하는 명령어이다.
psscan
프로세스를 트리 형태가 아닌 단순 출력을 통해 구조를 파악할 수 있는 명령어이다.
pstree
트리 형태로 하위 프로세스 구조를 파악할 수 있는 명령어이다.
psxview
psscan과 같이 은닉된 프로세스를 확인할 수 있는 명령어이다.
네트워크 분석
connections
현재 연결된 TCP 통신에 대한 정보를 Established 상태에 있을 때 출력해주는 명령어이다. (windows 7 미만 작동)
connscan
풀 태그 스캐닝 방식으로 연결을 파악하고, 종료된 연결까지 파악할 수 있게 도와주는 명령어이다.
netscan
메모리의 네트워크 정보와 프로세스 정보를 출력한다. (Linux, Window 환경의 netstat)
TCP, UDP 프로토콜로 이루어진 모든 통신을 조회한다. (IPv4, IPv6)
Sockets
TCP, UDP를 포함한 모든 프로토콜 통신에 대한 정보를 출력해주는 명령어이다. ( windows 7 미만 작동)
iehistory
메모리에 웹에 접근한 내용이 있다면 출력해 확인할 수 있는 명령어이다.
( 정보가 많을 때 ` iehistory >> ie.txt ` 명령어를 통해 txt 파일로 변환이 가능하다. )
cmd 분석
cmdscan, consoles
cmd 명령어를 확인할 수 있게 해주는 명령어이다.
cmdline
프로세스가 실행될 때의 인자값을 확인하게 해주는 명령어이다.
MFT 파서
mftparser
파일에 대한 메타데이터를 분석할 수 있게 해주는 명령어이다.
( 정보가 많을 때 ` mftparser >> mft.csv ` 명령어를 통해 csv 파일로 변환이 가능하다. )
파일 분석 및 덤프
filescan
` filescan | findstr "찾고자하는 문자" ` 명령어 입력을 통해 복구하고자 하는 파일을 찾을 수 있다.
메모리 내에 존재하는 파일들의 모든 리스트를 출력해주는 명령어이다.
dumpfiles
파일을 복구할 수 있게 해주는 명령어이다. 복구하고자 하는 파일명, 메모리 주소와 프로파일 명을 알아야 한다.
프로세스 세부 분석
memdump
입력했었던 명령어와 실행된 파일을 확인할 수 있게 해주는 명령어이다.
특정 프로세스 메모리 영역을 dump해준다. strings를 사용한다.
procdump
프로세스의 실행파일을 추출해주는 명령어이다.
기타
handles
프로세스에 의해 열린 핸들의 목록을 출력해주는 명령어이다.
vadwalk
VAD tree 자체 밸런싱 바이너리 트리 명령어이다.
printkey
지정된 레지스트리로 포함된 서브키, 값, 데이터와 데이터 형식을 출력할 수 있게 해주는 명령어이다.
malfind
악성코드에 대해 분석할 수 있는 플러그인이다. 자세한 내용은 malfind -h를 통해 확인할 수 있다.
userassist
레지스트리 정보를 바탕으로 실행되었던 응용 프로그램에 정보를 분석하는 명령어이다.
Volatility는 프로세스, 네트워크 정보, CMD 기록, 프로세스에 대한 메모리 덤프, 파일 복구, 히스토리 기능들이 있다.
잘 활용해보면 좋을 것 같다.
다음글이 없습니다.이전글이 없습니다.댓글