1. 정리

2. OLE

3. COM

4. WMI





1. 정리

  MSDN에 따르면 COM(Component Object Model)은 상호작용할 수 있는 바이너리 소프트웨어 컴포넌트를 생성하기 위한 플랫폼에 독립적이고 분산적이며 객체 지향적인 시스템이다. 개인적으로 COM 뿐만 아니라 .NET이나 WSH 그리고 WMI까지 모두 추상적인 개념들이라서 완벽히 이해는 못하더라도 간략한 메커니즘을 이해하려고 이렇게 정리한다. 물론 더 공부해 가면서 잘못 이해한 부분은 고치기도 하고 추가적인 내용을 덧붙이기도 할 것이다. 원래 파워셸이나 VBS, Powershell 등의 스크립트 언어를 이해하려다가 여기까지 왔지만 무턱대고 공부하기는 너무 힘들것 같아서 최대한 이해한 후 정리하려고 한다. 아마도 이해의 기준은 나일 것이므로 정리된 내용이나 이해한 부분도 내가 알고자 하는 것들 위주일 것이다.



  수 많은 설명들을 보면 대부분 어떤 의미에서든 COM을 어떻게 사용하는지에 대한 내용과 더욱 추상적인 개념들만 나와있다. 어쨌든 위의 개념들을 정리하기 위해서 이해한 내용은 COM은 메커니즘이라는 것이다. COM 객체가 생성된 경우 우리는 객체 내의 데이터를 참조하거나 조작할 수 있는데 이것은 COM 객체가 객체 지향형 인터페이스를 expose하기 때문이다. 즉 어디에선가 COM을 이용해서 인터페이스를 expose하면 COM을 사용할 수 있는 다른 곳에서도 마찬가지로 이 인터페이스를 이용해 데이터를 참조하거나 조작할 수 있을 것이다.



  기본적으로 윈도우 운영체제 자체도 많은 유용한 COM 객체들을 expose하며 IE나 MS Office도 자동화를 위해 많은 COM 인터페이스를 expose한다. 참고로 MS Office 등 어떤 애플리케이션들은 OLE Automation 객체를 제공하여 다른 애플리케이션이 이것과 커뮤니케이션할 수 있게 한다. exe 파일임에도 불구하고 export table이 있어서 OLE Automation을 위한 함수들을 내보내는 것이다. JS에서는 ActiveXObject() 객체를 사용하면 (참고로 IE만 지원한다) OLE Automation 객체의 인스턴스를 생성할 수 있다.



  이제 본론으로 넘어가서 VBS를 이용한 악성코드를 보면 대부분 WSH(Windows Script Host) 객체를 이용하는 것을 볼 수 있다. 예를들면 CreateObject 함수를 이용해 WScript.shell이라는 객체를 생성하고 특정 메소드를 사용하는 것이 대부분이다. WSH는 스크립트 기능을 제공해 주는데 이 기능은 COM 인터페이스들을 expose하는 객체 모델을 구현함으로써 가능해진다. VBS는 COM을 이용해서 이 인터페이스에 접근함으로써 WSH의 기능을 사용할 수 있다. 이렇듯 COM은 특정 기능을 사용할 수 있는 매개가 되는 방식으로서 사용된다.



  WSH 뿐만 아니라 WMI(Windows Management Instrumentation)도 마찬가지이다. 이것은 분산된 컴퓨터 시스템의 관리를 통합해 주는데 결론적으로는 통합된 인터페이스를 제공해주는 것이 목적이다. 이것도 관련 데이터 그리고 이것을 조작할 수 있는 메소드를 제공해 줄 것이다. WMI도 COM을 이용하며 이에 따라 C나 C++ 그리고 VBS 등에서도 WMI를 이용할 수 있다. 즉 COM은 WMI와 관리되는 윈도우 객체들 사이에서 매개 역할을 한다. 참고로 WMI 관련 내용은 Powershell과 함께 자주 나오는 편인데 이것은 .NET을 설명한 후에 같이 언급하기로 한다.



  .NET Framework는 윈도우 프로그램 개발 및 실행 환경으로서 간단히 말해서 여러 목적을 가지고 여러 기능이 구현되어 있는 플랫폼이다. 대표적으로 애플리케이션의 개발과 실행 시에 언어에 종속적이지 않은 플랫폼을 제공하기 위한 공통 언어 기반(CLI : Common Language Infrastructure)라는 개념이 있으며 이것은 표준이라고 할 수 있고 이 표준을 구현한 것이 공통 언어 런타임(CLR : Common Language Runtime)이다. 실질적으로 VM이라고 여겨지며 C# 등의 언어가 컴파일된 결과인 바이트코드를 실행시켜주는 역할을 한다. 이걸 설명이라고 할 수는 없겠지만 다음을 위해 적어보았다.



  파워셸은 .NET Framework를 기반으로 만들어진 객체 지향형 스크립트이다. cmdlet이라는 기본적인 명령어들은 내부적으로 .NET Framework Class Library를 이용해서 구현되었다. 중요한 점은 위에서도 언급하였듯이 WMI는 COM을 이용하여 인터페이스를 제공한다는 것이고 파워셸은 .NET Framework를 기반으로 만들어졌다는 점이다. 관련 내용을 찾아보니 .NET에서도 COM Inter-Op 메커니즘을 이용해 COM에 접근할 수 있다고 한다. COM을 직접 다루지는 않으므로 개발이 비교적 빠르지만 단점으로는 COM을 직접 사용하는 방식보다는 구조적으로 느릴 수 밖에 없다고 한다. 



  조금 더 설명하자면 RCW(Runtime Callable Wrapper), CCW(COM Callable Wrapper)라는 기능을 통해 COM과 .NET은 상대 기술로 제작된 오브젝트들을 사용할 수 있다고 한다. COM 클라이언트가 .NET 객체를 호출할 때 CLR은 객체와 이것을 위한 CCW를 생성한다. .NET 오브젝트를 직접 참조할 수 없기 때문에 COM 클라이언트는 CCW를 해당 객체를 위한 프록시로서 사용한다. 


  RCW는 COM 객체를 .NET 클래스에 expose하는데 사용됨으로써 .NET 코드가 COM 객체를 호출할 수 있게 한다. interop 어셈블리들은 원본 COM 타입에 대한 정보를 기술하는 .NET 메타데이터들을 포함하는데 CLR은 런타임 시에 이 정보를 이용해 RCW를 생성하고 .NET 응용 프로그램과 해당 COM 객체를 이어준다.



  지금까지의 설명은 COM에 대한 기본적인 설명부터 시작하여 COM을 매개로 하는 VBS 등의 스크립트와 WSH, WMI와의 관계 그리고 .NET Framework에 대한 기본적인 설명 및 파워셸 관련 내용이었다.





2. OLE

  추가적으로 COM의 역사와 관련하여 그리고 또 다른 중요한 내용인 OLE 그리고 ActiveX와 관련된 내용을 보겠다. 사실 이 부분은 앞의 부분보다 더더욱 헷갈리기도 하고 확실한 내용인지도 잘 모르겠다. 아무래도 이 문서는 자주 수정을 해야할 것이다.


  OLE(Object Linking and Embedding)는 문서와 다른 객체들 간에 삽입과 링킹을 지원해주는 기술이다. 예를들어 한 종류의 문서에서 다른 종류의 문서로 복붙이 가능해진다. OLE 1은 DDE(Dynamic Data Exchange)라는 기술을 기반으로 만들어졌다. DDE는 원본 데이터가 변경되면 애플리케이션에 통지하는 방식의 윈도우 메시지를 사용하여 구현되었다. 이후 DDE의 한계로 COM과 OLE 2를 설계하였고 COM을 기반으로 OLE 2를 만들게 된다. 어쨌든 앞에서 설명한 COM을 기반으로 만들어졌기 때문에 ole32.dll을 통해 OLE API 또는 COM API라고 불리는 여러 함수들을 expose하였고 다른 애플리케이션들이 이러한 기능에 접근할 수 있게 된다. COM API를 사용할 수 있게 되자 MS는 OLE Custom Control이라고 불리는 것을 개발하였는데 이것을 통해 OLE 객체들을 다룰 수 있게 되었다. 이후에는 이것을 확장하여 웹 브라우저에서도 사용할 수 있게 하였으며 이름을 ActiveX Control로 바꾸게 된다. [ ref : https://stackoverflow.com/questions/820614/com-ole-activex-idispatch-confusion ]


  ActiveX Control은 IE 브라우저의 Add-on으로서 COM과 OLE라는 기술을 이용해 플랫폼으로서의 역할을 하는 것으로 보인다. 예를들어 Adobe Flash Player가 ActiveX Control 기반 프로그램이다.





3. COM

  다음으로 COM과 관련한 간략한 내용과 악성코드에서 사용되는 방식에 대해서 다룬다.


  클라이언트는 CoCreateInstance()라는 COM API 함수를 이용해서 컴포넌트로부터 인스턴스 즉 객체를 생성한다. 이 함수는 매개변수로 컴포넌트 식별자와 Interface 식별자를 받는데 컴포넌트 식별자와 일치하는 컴포넌트를 찾아 객체를 생성하고 Interface 식별자와 일치하는 Interface를 찾고 이에 대한 포인터를 반환한다. 클라이언트는 이 Interface의 포인터를 이용해 원하는 COM 컴포넌트의 서비스를 받는다.


  이후 애플리케이션이 COM 서비스를 사용하기 위해서는 COM 라이브러리를 프로세스의 주소 공간에 로드시키고 이를 초기화해주어야 하는데 이때 CoInitialize()가 사용된다. 참고로 각 스레드별로 이것을 호출해서 COM 라이브러리를 초기화해주어야 한다.


  컴포넌트 식별자와 인터페이스 식별자는 GUID(Globally Unique Identifers)라는 같은 구조체를 사용하지만 각각 CLSID, IID로 구분하여 사용한다. CoCreateInstance() 호출 시 인자로 받은 CLSID와 일치하는 컴포넌트를 찾을 때는 레지스트리에서 찾는데 정확한 위치는 HKCR\CLSID\{CLSID들}이다. 추가 사항으로 IUnknown 인터페이스가 있는데 이것은 다른 모든 인터페이스들의 부모로서 모든 컴포넌트가 제공해야 하는 인터페이스이다.


  악성코드에서 사용되는 방식은 다음 링크를 참조한다. [ http://sanseolab.tistory.com/30 ]





4. WMI

  WMI와 관련해서는 다음 링크 [ https://msdn.microsoft.com/en-us/library/aa394553(v=vs.85).aspx ]에 매우 자세하게 나와있기 때문에 여기를 참조하면 될것으로 보인다.




'악성코드 분석' 카테고리의 다른 글

IDA Pro 시그니처 사용 및 제작 [ Flirt ]  (1) 2018.02.25
Anti-AV와 Anti-VM (Sandbox)  (1) 2017.12.30
exeinfo PE 사용법  (1) 2017.12.17
TEB 및 PEB를 활용하는 루틴  (1) 2017.12.04
EFLAGS 상태 레지스터  (0) 2017.11.22
Posted by SanseoLab

블로그 이미지
Malware Analyst
SanseoLab

태그목록

공지사항

Yesterday
Today
Total

달력

 « |  » 2024.4
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30

최근에 올라온 글

최근에 달린 댓글

글 보관함