상세 컨텐츠

본문 제목

Rhadamanthys Stealer 악성코드 분석 Part 1

악성코드 Malware/Stealer

by 0xmh 2023. 1. 28. 14:30

본문

728x90

요즘은 구글 광고 유포되는 악성코드가 유행인데요 그중에 12월 말에 처음으로 Malwarebazaar에 나타난 Rhadamanthys이라는 Stealer 악성코드도 하나입니다. 피해자의 소중한 개인정보를 탈취하는 악성코드이므로 이 블로그에서 분석했던 RacoonStealer하고 OskiStealer 악성코드와 매우 비슷하나 분석해 보니 Rhadamanthys가 두 악성코드들보다 더 sophisticated이다! 라는 생각을 들었습니다. 

그 이유는 Rhadamanthys가 자신의 마지막 payload를 실행 시키기 전에 다양한 단계들을 거쳐서입니다. 아울러 Rhadamanthys는 Shellcode와 제가 지금까지 본 적 없는 재밌는 shellcode 실행 방식을 쓰기 때문에 분석이 매우 재밌었네요. 이 분석은 두 파트로 나누고 오늘 블로그는 위에서 언급했던 "final payload"까지의 단계들을 분석하도록 하겠습니다.


Stage 1: Loader

PEStudio를 열자마자 entropy가 높은 것이 보이기에 이 샘플은 높은 확률 packing되어 있거나 안에 다른 payload가 숨어 있을 것입니다. 아울러 실행파일 "description"을 보면 notepad++이라는 소프트웨어를 모방하고자 하는 것이 보입니다. 위에서 말했던 바와 같이 이 악성코드도 Google Ads로 유포되므로 notepad++를 쓰려는 사람들을 공격하기 위해서 만든 것이 아닌가 싶었습니다.

1. PEStudio

첫 번째 stage는 그리 흥미롭지가 않아 바로 핵심 포인트로 넘어가겠습니다. Rhadamanthys는 Stackstring들을 활용하여  LoadLibrary로 cabinet.dll이라는 dll 파일을 불러오는데 다음의 stage를 위한 필수 단계입니다.

2.Cabinet.dll

cabinet.dll를 활용하여 다음 function들이 import됩니다.

FDICreate, FDICopy, FDIIsCabinet, FDIDestroy

3. Decryption

아울러 3번 사진을 보면 악성코드가 rc4 decryption과 "Rust Analyzer 02"라는 key로 데이터를 decrypt한다는 것을 확인할 수 있는데 바로 Stage2 셸코드입니다. Cyberchef로 decrypt해보니 MSCF 해더가 보이는데, 윈도우의 .cab 파일의 해더입니다. archive 파일이기 때문에 다운로드하여 열면 됩니다.

4. Cyberchef

열어보니, 파일 2개 보이는데 1.bin이라는 파일이 Stage2 셸코드입니다

5. CabFile

다음으로는 셸코드 실행 방식을 설명하도록 하겠습니다. 

FDICreate라는 API로 (3번 사진 참고) 먼저 "FDI context"라는 것을 만들고 이에 대한 microsoft의 documentation을 보면 FDI 관련 함수들은 callback를 씁니다. FDICreate의 마지막 인수는 "1"인데, Intel 80386 명령어를 쓴다는 것입니다.

가장 중요한 부분은 다음의 FDICopy 함수입니다. FDICreate 함수의 FDI context를 받아, "pszCabinet" 인수로 cab 파일의 이름을 받고, pszCapPath는 cab 파일의 위치 (path)를 받습니다. 이 함수의 핵심은 "pfnfdin" 인수이며 윈도우에 따르면 "callback notification function to update the application on the status of the decoder"입니다. 

6. FDICopy

decode 과정이 끝난 다음에 LocalAlloc이 사용되는데 높은 확률로 다음 stage를 위한 메모리를 할당하는 역할을 하고 jmp 명령어를 활용하여 다음으로 실행되는 코드로 점프합니다.

7. LocalAlloc

Stage 2: First Shellcode

첫 번째 셸코드는 매구 작고 Stage 3 셸코드를 위한 로딩 역할을 합니다. 모든 셸코드처럼 이 코드도 fs:30h라는 어셈블리 명령어로 ProcessEnvironmentBlock (PEB)를 불러옵니다. 그래야 그 다음으로 kernel32.dll에서 필요한 함수들을 사용할 수 있습니다.

모든 셸코드가 다음 패턴을 따릅니다.

8. PEB

IDA의 pseudocode가 여기 Structure들을 잘못parse 해준 것 같은데 중요한 부분은 소문자/대문자 k입니다! Kernel32.dll 찾는다는 것이죠.

9. PEB Walk

kernel32.dll를 찾은 다음에 필요한 함수들을 찾아보고 hash_function이라는 함수로 받은 kernel32.dll안에 있는 함수들을 받고 debugger로 확인해 보니 "LocalAlloc, VirtualAlloc, LocalFree, VirtualFree"입니다. 악성코드가 메모리를 할당하는 함수를 또 사용하는 것을 보니 stage를 하나 더 기대해야겠네요.

10. kernel32.dll

7번 사진과 비슷하게 다음 셸코드도 jmp 명령어로 실행되는 것 같습니다. x64dbg로도 그 사실을 확인할 수 있고, call ebx에 도착하면 "Jump into"를 누르면 Stage3의 셸코드 분석할 수 있습니다!

11. Shellcode JMP
12. Shellcode JMP x64dbg

Stage 3: Second Shellcode

두 번째 셸코드는 다양한 Evasion 기능도 가지고 있으며, Exception Handling, C2서버 통신, UAC bypass을 기능을 활용하는 것을 확인할 수 있습니다.

 

Rhadamanthys 악성코드의 Evasion 기능을 보고 "Bumblebee랑 똑같네?" 라는 생각이 들었는데 오랜만에 다시 검색해 보니 open-source인 github의 코드를 사용하더라고요. (https://github.com/LordNoteworthy/al-khaser

깃허브에 다 확인이 가능하니 몇 개만 언급하겠습니다.

 

1. 다양한 VM과 hypervisor 확인.

13. Evasion 1

2. Registry를 불러 VM 소프트웨어 확인

14. Evasion 2
15. Evasion 3

3. 잠재적 악성코드 분석의 랩환경에 대한 string 테스

16. Evasion 4

4. WMI 활용하여 시스템에 VM 관련 소프트웨어가 설치되어 있는지 확인

15. Evasion 5

5. VM 소프트웨어 드라이버 확인

16. Evasion 16

흥미롭다고 생각했던 Evasion 기술 중에 하나가 ZwQueryInformationProcess하고 KiUserExceptionDispatcher 조합이었는데 간단하게 설명해 보자면. 먼저 GetModuleHandleA로 ntdll.dll 핸들을 받아보고 GetProcAddress로 ZwQueryInformationProcess을 API를 받습니다. GetCurrentProcess로 현재 작동 중인 프로세스의 handle을 받습니다.

17. Exception Handle 1

똑같은 API들을 활용하여 KiUserExceptionDispatcher API를 받아보는데 제가 완전 처음으로 본 것이라서 아직도 100% 이해했는지 모르겠지만...

http://www.nynaeve.net/?p=201 이 블로그에 따르면 KiUserExceptionDispatcher가 SEH (Structured Exception Handling) dispatcher를 불러오는 역할을 한다고 합니다. while loop을 보니 코드가 KiUserExceptionDispatcher 안에서 무언가를 찾으려고 하는 것 같은데 밑에 있는 VirtProtect를 보니 "hooking"인가 싶었습니다.

18. Exception Handle 2

VirtProtect이라는 함수는 다음과 같습니다. VirtualProtect API로 실행 권한을 PAGE_EXECUTE_READWRITE으로 바꿨다가 다시 PAGE_READWRITE로 바꾸는 것을 확인할 수 있습니다. (0xE8로 hook 박아놓는 것 같은데 설명해 주실 분 ... ㅎㅎ)

19. Exception Handle 3

VirtProtect 함수에서 return한 다음에 코다가 SetErrorMode를 사용하는데 에러가 생긴 경우에 그것을 드러나지 않기 위해서입니다.

20. Error

통신 서버 관련 기능은 이제부터 나옵니다.

21. C2 Action

 20번 사진에 다른 rc4 decryption 루틴이 보이는데 그 루틴의 결과를 가지고 "0x59485221"하고 비교하는데 어셈블리 명령어를 확인해 보니 decrypt된 데이터는 통신서버의 아이피입니다 --> hxxp://164[.]90[.]172[.]224

22, C2 Address

통신서버의 4번째 스테이지를 다운로드하기 전에 C:\Users\유저이름\AppData\Local\Temp\\nsis_unsb[랜덤].dll이라는 파일을 생산시키는데 보시다시피 .dll파일입니다.

23. 4th Stage 1

dll 파일을 받은 후에 PrintUIEntrty라는 Export Function을 실행시킵니다. 제가 이 샘플을 분석했을 때 C2 서버가 더 이상 작동하지 않았기 때문에 마지막 스테이지의  payload를 받지 못했습니다. MalwareBazaar나 다른 홈페이지들을 좀 뒤져보고 그 payload를 다음 블로그에서 분석하겠습니다!

24. 4th Stage 4

그리고 마지막으로는 .dll 파일을 당연히 rundll32.exe로 실행시키네요!

25. 4th Stage 3

Rhadamanthys 현재 작동 중인 프로세스의 권한도 확인하는데 mw_TokenInfo 안에서는 GetTokenInformation으로 토켄을 확인하고 토켄의 SidUsbAuthority도 확인합니다. 그 value가 0x2000보다 (Medium integrity level  SECURITY_MANDATORY_MEDIUM_RID) "작으면" --fast이라는 string을 Commandline에 넘겨 ShellExecute하고 "runas"이라는 명령어로 다시 실행시킵니다. 즉, Rhadamanthys은 악성코드를 실행시킨 유저의 권한이 너무 낮으면 runas으로 UAC Bypass를 시도합니다.

26. UAC Bypass 1
27. UAC Bypass 2

셸코드 안에 무슨 에러가 있었는지 아니면 제가 분석하면서 실수를 했는지... 그러나 분석하면서 다음 루틴도 발견했는데 cross-reference가 존재하지 않아 이 다음 코드가 어디서 실행되는지 잘 모르겠습니다. 하지만 딱 보면 피해자 시스템이 통신서버에 연결하여 다양한 정보를 보내는 것 같습니다!

28. C2 Send

 

비슷하게 다음과 같은 코드도 발견했는데 이 코드도 cross reference가 없어서 분석이 힘들었지만 따로 ntdll.dll 불러오는 것을 보니 그 이유는 아마 userland hooking 피하기 위해서인 것 같습니다!

관련글 더보기