2016년 4월 5일 화요일

[많은 보안 솔루션을 보유한 I사를 겨냥한 악성코드/Dark Hotel] 악성코드 분석 Part.1 / Malware Analysis Part.1

* 서론

2016년 2월 경, 많은 보안 솔루션을 보유한 I사 내부로 침투한 악성코드이다.

해당 악성코드는 I사 내부에 있는 공인인증서를 탈취했다고 알려져있다.

악성코드 명칭은 RIFLE(가칭), 유형은 Backdoor이며, 제작한 곳은 "Rifle Campaign"으로 추정한다.

대략 6개 가량의 샘플이 발견되었다.

그 중 1개를 분석한다.

* 환경

(1) WINDOWS 7
(2) IDA Pro, OllyDBG, ExeInfo PE, HxD, NotePad++ 등


* 분석

0. 들어가기 전

<그림 0. 악성코드 과정>



<그림 1. 샘플 #1 PE 정보>

1. Socket 초기화


<그림 2. Socket을 사용하기 위해 WSA를 초기화 과정>

2. C&C 서버 연결

<그림 3. C&C 서버 연결 과정>

C&C 서버 IP/Port : 192[.]99[.]223[.]115[:]8080

3. 해상도 구하기


<그림 4. GetSystemMetrics API를 이용하여 해상도 구하기>


<그림 5. GetSystemMetrics API>
https://msdn.microsoft.com/en-us/library/windows/desktop/ms724385(v=vs.85).aspx


4. SID 검색하여 현재 로그인 된 WINDOWS 계정 권한 확인


<그림 5. SID 검색하여 계정권한 찾는 과정>


<그림 6. GetTokenInformation API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/aa446671(v=vs.85).aspx

<그림 7. AllocateAndInitializeSid API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/aa375213(v=vs.85).aspx

5. PC의 Processor 이름 구하기

<그림 8. 레지스트리를 통해 Processor 이름 얻어오는 과정>

6. WINDOWS 로그인 된 사용자명 얻어오기

<그림 9. GetUserName API를 이용하여 사용자명 얻어오는 과정>

<그림 10. GetUserName API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/ms724432(v=vs.85).aspx

7. IP 주소와 현재 Hostname 얻어오기

<그림 11. IP Address와 Hostname 얻어오는 과정>


<그림 12. gethostname API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/ms738527(v=vs.85).aspx

<그림 13. gethostbyname API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/ms738524(v=vs.85).aspx

<그림 14. inet_ntoa API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/ms738564(v=vs.85).aspx

8. WINDOWS Version 구하기

<그림 15. 시스템 버전 얻어오는 과정>


<그림 16. GetNativeSystemInfo API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/ms724340(v=vs.85).aspx

<그림 17. GetSystemInfo API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/ms724381(v=vs.85).aspx

<그림 18. 레지스트리 내 WINDOWS Version 명 얻어오는 과정>

9. 메모리 크기 얻어오기

<그림 19. GlobalMemoryStatus를 이용하여 메모리 크기 얻어오는 과정>


<그림 20. GlobalMemoryStatus API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/aa366586(v=vs.85).aspx

10. 얻어온 시스템 정보를 C&C 서버로 전송


<그림 21. sprintf를 통해 시스템정보를 하나의 Buffer로 모으는 과정>



<그림 22. 시스템정보를 ZLIB로 Compress 후 XOR로 Encoding>

* ZLIB의 버전은 1.1.4

<그림 23. ZLIB의 compress API>
http://www.zlib.net/manual.html

DWORD EncodeXOR(LPBYTE data, DWORD dwSize)
{
 DWORD dwResult, i = 0;

 DWORD XORKey1;
 BYTE XORKey2 = 0x27, XORKey3 = 0x13, XORKey4;

 XORKey1 = 0x7A188913;
 for (dwResult = 0xF4460304; i < dwSize; XORKey1 = (((XORKey1 ^ (8 * XORKey1)) & 0x7F8) << 20) | (XORKey1 >> 8))
 {
  data[i] ^= XORKey2 ^ dwResult ^ XORKey3;
  XORKey4 = XORKey3 & (XORKey2 ^ dwResult);
  XORKey3 = (((XORKey1 ^ (8 * XORKey1)) & 0x7F8) << 20) | (XORKey1 >> 8);
  XORKey2 = XORKey4 ^ dwResult & XORKey2;
  dwResult = (((dwResult << 7) ^ (dwResult ^ 16 * (dwResult ^ 2 * dwResult)) & 0xFFFFFF80) << 17) | (dwResult >> 8);
  i++;
 }

 return dwResult;
}

LPBYTE CompressData(LPBYTE lpData, DWORD dwSize, DWORD EncodeSize)
{
 int nRet;
 LPBYTE lpResult;

 lpResult = (LPBYTE)malloc(sizeof(BYTE) * dwSize);
 if (lpResult)
 {
  memcpy(lpResult, lpData, dwSize);
  nRet = compress((Bytef *)lpData, (uLongf *)&EncodeSize, (Bytef *)lpResult, (uLong)dwSize);

  if (nRet)
  {
   lpResult = NULL;
  }
  else
  {
   lpResult = (LPBYTE)EncodeSize;
   EncodeXOR(lpData, EncodeSize);
  }
 }

 return lpResult;
}

11. Compress 과정 이후 사이즈와 데이터를 결합하여 C&C 서버로 전송


<그림 24. C&C서버로 데이터 전송>

12. C&C 서버로 부터 명령 전달받기

<그림 25. C&C 서버로 부터 Command를 Loop 돌며 계속 받아오는 과정>

<그림 26. C&C 서버로 받은 데이터를 Uncompress 처리하여 가져오는 과정>

<그림 27. Uncompress 과정>

* XOR은 Encoding 했던 값으로 다시 Encoding을 하게 되면 Decoding이 된다. (상식!)
* ZLIB로 Compress 했기 때문에 Uncompress 해야 한다.

13. 프로토콜 목록


<그림 28. 프로토콜 목록>

14-1. 실행중인 프로세스 목록 가져오기 (2002)


<그림 29. 실행 중인 프로세스 목록 가져오는 과정>


<그림 30. CreateToolhelp32Snapshot API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/ms682489(v=vs.85).aspx

<그림 31. Process32Next API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/ms684836(v=vs.85).aspx

<그림 32. EnumProcessModules API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/ms682631(v=vs.85).aspx

<그림 33. GetModuleFileName API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/ms683197(v=vs.85).aspx

14-2. 프로세스명 기반으로 특정 프로세스 강제종료 (2003)

<그림 34. 프로세스 명 기반으로 특정 프로세스 강제종료 과정>

<그림 35. OpenProcess API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/ms684320(v=vs.85).aspx

<그림 36. TerminateProcess API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/ms686714(v=vs.85).aspx

14-3. 사용자가 보고 있는 프로세스의 WINDOW명 얻어오기 (2004)

<그림 37. 최상위 WINDOW를 가져와 WINDOW 명을 가져오는 과정>
 
<그림 38. 다음 WINDOW를 가져와 WINDOW명 가져오는 과정>
 
<그림 39. 현재 찾은 WINDOW가 화면에서 활성화가 되고 있는 확인 하는 과정>


<그림 40. GetForegroundWindow API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/ms633505(v=vs.85).aspx

<그림 41. GetWindowText API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/ms633520(v=vs.85).aspx


<그림 42. IsWindowVisible API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/ms633530(v=vs.85).aspx

* 현재 실행되고 있는 모든 WINDOW 탐색

14-4. WINDOW명 기반으로 특정 프로세스 강제종료 (2007)


<그림 43. WINDOW명 기반으로 특정 프로세스 강제종료하는 과정>

<그림 44. SendMessage API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/ms644950(v=vs.85).aspx
<그림 45. WM_CLOSE Message>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/ms632617(v=vs.85).aspx

* SendMessage로 WM_CLOSE를 전송하여 프로세스 강제종료

14-5. 전체 시스템 드라이브 유형 검색 (2010)


<그림 46. 전체 시스템 드라이브 유형 검색하는 과정>

<그림 47. GetDriveType API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/aa364939(v=vs.85).aspx

* A~Z 드라이브까지 전체 검색하여 유형을 C&C 서버로 전달

14-6. 드라이브 내 파일 검색 (2012)

<그림 48. 파일 찾기 위해 초기화>


<그림 49. 드라이브 내 파일 검색하는 과정>


<그림 50. FindFirstFile API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/aa364418(v=vs.85).aspx

<그림 51. FindFirstFile API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/aa364418(v=vs.85).aspx
<그림 52. FindNextFile API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/aa364428(v=vs.85).aspx

* 폴더 내 스캔하는 전형적인 알고리즘

14-7. 특정 경로로 파일 복사 (2014)

<그림 53. CopyFile를 이용한 특정 경로로 파일 복사하는 과정>

<그림 54. CopyFile API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/aa363851(v=vs.85).aspx

14-8. 특정 파일 삭제 (2016)



<그림 55. DeleteFile를 이용한 특정 파일 삭제 과정>

<그림 56. DeleteFile API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/aa363915(v=vs.85).aspx

14-9. 특정 경로로 파일 이동 (2018)

<그림 57. MoveFile를 이용한 특정 경로로 특정 파일 이동하는 과정>

<그림 58. MoveFile API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/aa365239(v=vs.85).aspx

14-10. 특정 파일명으로 특정 내용 쓰기 (2020)

<그림 59. fwrite로 파일 쓰기>

<그림 60. fwrite API>
https://msdn.microsoft.com/ko-kr/library/h9t88zwz.aspx

14-11. C&C 서버로 특정 파일 보내기 (2022)

<그림 61. C&C로 파일 보내기 위한 과정>


<그림 62. fopen API>
https://msdn.microsoft.com/ko-kr/library/yeby3zcb.aspx

<그림 63. fseek API>
https://msdn.microsoft.com/ko-kr/library/75yw9bf3.aspx

<그림 64. fread API>
https://msdn.microsoft.com/ko-kr/library/kt0etdcs.aspx

* fopen으로 파일 읽어서 fseek를 통해 파일 총 크기를 구하고 fread를 통해 데이터를 읽어 C&C 서버로 전송

14-12. 시스템 드라이브 폴더 검색 (2024)

<그림 65. 시스템 드라이브 폴더 검색 과정>

* 2012 프로토콜과 비슷한 것으로 판단

14-13. 특정 프로세스 실행 (2026)

<그림 66. 특정 프로세스 실행하는 과정>

<그림 67. ShellExecute API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/bb762153(v=vs.85).aspx

 

* Index에 따라 숨겨서 실행(SW_HIDE)하거나 일반 실행(SW_SHOW)하게 된다.

14-14. 현재 WINDOWS 화면을 0.1초마다 C&C 서버로 전송 (2050)

<그림 68. 스크린 캡쳐를 위한 초기화하는 과정>


<그림 69. 캡쳐 대상을 Desktop으로 지정하는 과정>
<그림 70. 대상을 캡쳐하는 과정 #1>



<그림 71. 대상을 캡쳐하는 과정 #2>
 
<그림 72. GetClientRect API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/ms633503(v=vs.85).aspx

<그림 73. CreateCompatibleDC API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/dd183489(v=vs.85).aspx

<그림 74. GetDC API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/dd144871(v=vs.85).aspx

<그림 75. CreateCompatibleBitmap API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/dd183488(v=vs.85).aspx

<그림 76. GetDIBits API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/dd144879(v=vs.85).aspx

<그림 77. CreateDIBSection API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/dd183494(v=vs.85).aspx


<그림 78. SelectObject API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/dd162957(v=vs.85).aspx

<그림 79. Bitblt API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/dd183370(v=vs.85).aspx

* 상당히 복잡해보이지만, C++ 내 그래픽 처리하는 과정은 보통 이정도 과정이 된다.
* 구글 검색하면 위 수준의 알고리즘은 금방 발견할 수 있다.

14-15. 특정 서비스 시작 (2081)

<그림 80. 특정 서비스 시작하는 과정>

<그림 81. OpenSCManager API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/ms684323(v=vs.85).aspx

<그림 82. OpenService API>
https://msdn.microsoft.com/en-us/library/windows/desktop/ms684330(v=vs.85).aspx

<그림 83. StartService API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/ms686321(v=vs.85).aspx

14-16. 특정 서비스 정지 (2082)


<그림 84. 특정 서비스 정지 하는 과정>

<그림 85. QueryServiceStatusEx API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/ms684941(v=vs.85).aspx

<그림 86. ControlService API>
https://msdn.microsoft.com/en-us/library/windows/desktop/ms682108(v=vs.85).aspx


* ControlService를 통해 SERVICE_CONTROL_STOP 명령을 보내 서비스를 중지시킨다.

14-17. 시스템에 설치된 프로그램과 설치경로 얻어오기 (3010)

<그림 87. 레지스트리를 통해 시스템에 설치된 프로그램과 설치경로 얻어오는 과정>
* "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\" 레지스트리 경로에는 시스템에 설치 된 프로그램과 설치경로가 존재한다.

14-18. CMD.EXE 파이프 생성 및 명령어 받기 (4001)


<그림 88. CMD.EXE를 파이프로 생성하는 과정>


<그림 89. 파이프 통신하는 과정>


<그림 90. CreatePipe API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/aa365152(v=vs.85).aspx

<그림 91. CreateProcess API>
https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx


<그림 92. PeekNamedPipe API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/aa365779(v=vs.85).aspx

<그림 93. ReadFile API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/aa365467(v=vs.85).aspx

 * C&C에서 내린 명령어를 수월하게 처리하기 위해 PIPE를 열어둔 것으로 파악된다.

14-19. 파이프로 수행한 명령어 결과 보내기 (4002)


<그림 94. 파이프로 수행한 결과 보내는 과정>


<그림 95. WriteFile API>
https://msdn.microsoft.com/ko-kr/library/windows/desktop/aa365747(v=vs.85).aspx

* 결론

해당 악성코드는 Backdoor를 목적으로 둔 악성코드이다.

I사는  인증서를 탈취당했다고 전해진다.

악성코드의 기능을 보아하면 인증서 외 다른 것도 탈취 및 공격 당했을 가능성이 충분히 농후해 보인다.

댓글 1개

  1. 안녕하세요. 악성코드 분석에 관심이 많은 학생입니다.

    분석하신 자료에 대해서 잘 읽었습니다.

    잘 정리되어 있고 전문성이 느껴지는 분석 보고서를 잘 읽었습니다.

    제가 직접 바이너리를 분석해보고 싶은데 혹시 메일로 보내주실 수 있으신지 궁금합니다.

    혹시 보내 주실 수 있으시면

    rhrhkddn22@naver.com 으로 보내주시면 감사하겠습니다.

    답글삭제

© NoFaceLab
Maira Gall