작은 메모장

악성HWP문서 분석_익스플로잇 3 본문

KISA 사이버 보안 훈련/스피어피싱 대응 심화

악성HWP문서 분석_익스플로잇 3

으앙내눈 2023. 5. 30. 18:53

이번 목표 문서

 

트리아지

늘 그렇듯 데이터 스트림부터 확인

BIN0001.eps 스크립트가 잡힘

이전 사례에서도 보았듯, 포스트 스크립트는 정상적인 문서에서는 나오기 힘듬

악성 공격이 들어간 스크립트라고 판단 가능

 

이 스크립트를 별도의 파일로 추출

zlib으로 압축되어 있을 것이므로, 압축 또한 해제

정상적인 압축 해제가 된 모습

코드가 난독화가 되어있는 모습

저번처럼 def를 기준으로 줄바꿈을 실행

스크립트는 간단한 구성

Y101변수에 뭔가 엄청나게 긴 데이터를 넣고

이를 Y18변수와 xor연산을 한 뒤 exec 함수로 실행시킴

=> exec 지우고 고스트 스크립트 위에서 어떻게 돌아가는지 보면 됨

실행키시면 스택에 값 하나가 들어있는것을 볼 수 있음

이 값은 아까 엄청나게 긴 값이 디코딩 된 스크립트

16진수로 엄청나게 많은 양의 데이터가 있는 것을 확인 가능

이 코드가 스크립트 안에 들어있는 쉘코드로 판단

이를 다시 hex변환

Cyberchef를 통해 엄청나게 긴 코드를 hex로 변환함

쉘코드가 어떻게 동작하는지 확인하려면 디버거를 통해서 확인해야함

저번처럼 평범한 계산기 프로그램을 열고 메모리에 쉘코드를 주입

이후, 쉘코드 시작점부터 EIP를 설정하여 분석할 준비를 마침

 

스크립트 코드 분석

코드의 시작은 puched으로 시작함

범용 레지스터의 값을 stack에 저장하는 명령

코드 아래쪽에 이를 다시 사용하기 위한 pop명령어 또한 존재

전반적인 코드는 뜻을 알 수 없는 의미없는 코드가 가득

의미있는 시그니쳐도 안보이고, API 리졸빙 과정 또한 안보임

=> 쉘코드 자체가 인코딩 되었음

코드 중간에 보면, 쉘코드 부분을 XOR연산하는 부분이 있음

이 부분에 중단점을 집고 코드를 실행

EDI의 값은 034F0009임

여기에 17을 더하고 XOR 연산을 시행하므로 034F0026코드부터 변환될거임

한단계씩 디버깅을 해보면, 서서히 난독화가 풀리고 있는 모습을 확인 가능

루프가 끝나는 구간에서 중단점을 집고 다시 코드를 분석

디코딩을 마친 코드에서 처음으로 나오는 것은 무언가 call

call하는 대상을 보니, 이 주소에 해당하는 코드가 존재

이 주소에 해당하는 코드로 진입

또 무언가를 call하는 모습

이는 FS 레지스터에서 PEB를 가져와 API 리졸빙을 수행하는 코드

리졸빙이 끝난 코드가 어떤 값을 반환하는지 살펴 봄

해당 call에 중단점을 집고 실행, 한 단계 더 실행

스택에는 getModuleFileNameA이라는 함수가 들어있음

코드를 살펴보면 또 무엇인가를 call하는 코드가 존재

여기도 중단점을 집고 한단계만 실행

오른쪽의 ESP값에 현재 실행중인 프로세스의 경로를 포함한 파일명이 담겨짐

또다른 call을 부르는 곳

희안하게 여기는 ecx값을 계속 바꾸면서 똑같은 주소를 호출하고 있음

call을 할 때마다 어떤 값을 불러 스택에 저장하는지 살펴 봄

첫 번째 call시 불러진 함수

CreateUserThread라는 함수

두 번째 call시 불러진 함수

wClose라는 함수

세 번째 call시 불러진 함수

OpenProcess라는 함수

네 번째 call시 불러진 함수

VirtualAllocEx라는 함수

다섯 번째 call시 불러진 함수

writeProcessMemory라는 함수

여섯 번째 call시 불러진 함수

VirtualProtectEx라는 함수

 

정리하면, 위 과정을 거치면서 총 6가지의 함수의 주소를 스택에 저장하는 코드

이 과정을 거치면, 일련의 과정을 거치며 API 리졸빙 과정을 수행하는 것을 확인 가능

스택을 확인하면 GetCurrentProcess와 IsWow64Process API를 반환받아 실행

다음 call때도 마찬가지로, 일련의 과정을 거치며 API 리졸빙 과정을 수행하는 것을 확인 가능

스택을 확인하면 CreateToolHelp32Snapshot, Process32First 및 Process32Next API를 반환받아 실행

이걸 왜 씀? => 공격자가 특정 프로세스를 찾기 위해 사용

explorer.exe라는 이름이 명시되어 있는 것으로 보아, explorer 프로세스를 찾고 있는 것으로 보임

다음 call때도 마찬가지로, 일련의 과정을 거치며 API 리졸빙 과정을 수행하는 것을 확인 가능

스택을 확인하면 OpenProcessToken, AdjustPrivilegesToken, Close 및 GetCurrentProcess API를 반환받아 실행

아까 찾았던 explorer의 토큰값을 획득하고 프로세스 권한을 확인

다음 call을 살펴보면, OpenProcess함수가 호출됨을 확인할 수 있음

인자로 주어지는 값은 프로세스 ID, 위 일련의 과정을 통해 얻었던 explorer의 PID 값

즉 PID값으로 핸들을 획득하고 OpenProcess로 프로세스를 실행함

다음 call에서의 행위

획득한 핸들을 들고 VirtualAllocEx 함수를 통해 프로세스에 페이지를 할당

이와 동시에 EAX 레지스터 값을 복사

다음 call에서의 행위

WriteProcessMemory 함수를 통해 아까 복사한 프로세스 메모리 주소를 주입

다음 call에서의 행위, 여기선 볼 것이 많음

일단 VirtualProtectEx 함수를 통해  페이지에 권한을 부여

근데 무슨 권한을 부여함?

옆에 stdcall 항목을 보면 esp값을 볼 수 있음

여기에는 프로세스 핸들러, 할당된 메모리 페이지 주소, 메모리 사이즈, 권한 부여 여부 설정값이 부여되어 있음

4번의 권한 부여 값에 의해 explorer.exe의 메모리 페이지 주소에는 읽기/쓰기/실행 권한이 부여

 

한가지 문제가 있다면, explorer.exe는 32비트가 아닌 64비트에서 돌아가는 프로세스

때문에 흐름을 제대로 쫓으려면 64비트 디버거에서 explorer.exe를 쫓아가야함

붙여넣은 explorer는 어디가 진행되고 있는지를 모름

때문에 아까 PID가 저장된 메모리 주소 값을 입력

추적하면 이렇게 주입된 값을 찾을 수 있음

이를 복사하여 파일로 따로 저장

이제 explorer는 64비트 흐름으로 돌아가기 때문에, 64비트 환경에서 저장했던 값을 다시 세팅

64비트 디버거에서 다시 계산기 연 후 메모리에 쉘 코드 주입

쉘코드 시작 부분에 EIP를 설정하고 다시 쉘코드 분석 시작

32비트와는 달리, 64비트는 구조가 의외로 간단함

GS레지스터에서 PEB를 가져오는 모습

물론 API 리졸빙을 하기 위함

아래로 내리다보면, 특정 값에서 jmp를 하는 것을 볼 수 있음

여기에 중단점을 잡고 실행

RAX 레지스터가 WinExec함수를 호출하고 인자값으로 사용하는 RCX 레지스터 값을 사용함

RCX 레지스터에는 일련의 powershell명령이 들어가 있는데, 이를 자세히 분석

해당 코드가 나옴

이 코드는 특정 인터넷 주소에서 Util.exe파일을 다운받아 실행하는 코드

C2서버의 주소를 알아냄