본 포스팅의 원문출처는 Volatility Labs이며, 2016년 8월 2일에 게시된 원문 글의 제목은 Automating Detection of Known Malware through Memory Forensics 입니다. 해당 블로그의 글을 번역하여 포스팅합니다. 


* 이 글에는 Volatility Framework와 ClamScan이 사용되며, 설치방법에 대해서는 별도로 설명하지 않습니다.

** 여기에서 쓰인 '악성코드 탐지'라는 단어는 모두 '(알려진)악성코드'에 대한 탐지를 의미합니다. 즉, 이미 알려진 멀웨어에 대한 시그니처와 비교해서 탐지하는 방식이므로, 알려지지 않은 새로운 형태의 위협에 대해서는 미탐지(False Negative)가 발생할 수 있습니다.


이번 포스팅에서는 볼라틸리티(Volatility) 플러그인 3개와 *ClamAV(Clam AntiVirus)를 사용하여, 악성코드로 알려진 것들을 자동으로 탐지하는 방법을 소개하고자 합니다. 여기에서는 Microsoft Windows 환경을 기준으로 설명하고, 혹시 리눅스나 macOS에 적용하고자 하시는 분들을 위한 간단한 설명도 글의 마지막에 첨부하도록 하겠습니다.

*역자 주 : ClamAV(Clam AntiVirus)는 네트워크장비로 유명한 시스코 시스템즈에서 지원하는 오픈소스 소프트웨어로 자유 크로스플랫폼 형식의 바이러스 검사 소프트웨어 툴킷이다. (출처: 위키백과)


1. 들어가기에 앞서

여러분이 만약 악성코드 분석가라면 나날이 쏟아지는 새로운 형태의 멀웨어 샘플들을 분석하는 것이 물론 재미있겠지만, 실제로는 ‘이미 악성코드로 알려진’ 것들을 구체적으로 검증하기 위해 해당 멀웨어의 행위가 담긴 메모리 샘플을 분석하는 것이 업무의 대부분을 차지할 것입니다. 이러한 경우라면, 기존의 툴이나 관련 정보들을 적절히 활용할 수 있는 능력만 있다면 감염 시스템에서 매우 신속하고 효과적으로 멀웨어를 식별해낼 수 있습니다.


본 포스팅에서는 시스템에서 악성 소프트웨어의 존재유무를 성공적으로 조사할 수 있도록하는 방법론을 정리하여 제시하고자 합니다. 여기에서 제안하는 과정을 잘 따라하시면, 현재 분석을 수행하고 계신 메모리 샘플을 효과적으로 처리한 후, 발견된 위협요소에 대해 적절한 예방작업이나 후속조치를 수행하실 수 있을 것입니다.


2. 환경설정

구체적인 설명을 위해서, 온라인에서 쉽게 구할 수 있는 메모리 샘플 하나를 예시로 들겠습니다. 악성코드 분석가의 비법서(에이콘출판 역간, 원제 : The Malware Analyst’s Cookbook)라는 책에 포함된 stuxnet.vmem 샘플을 채택하도록 하겠습니다. 이름에서 알수있듯이, 이 샘플은 스턱스넷에 감염된 가상머신의 메모리를 덤프한 것입니다.


여기에서 시나리오로 주어지는 상황은 자신의 시스템이 감염되었는지 여부를 확인하고자 하는 것입니다. 백신프로그램(AV) 또는 침입탐지시스템(IDS)의 경고를 받은 경우, 또는 잠재적 위협을 피하기 위해 사전 예방적으로 수행하기 위해 해당 시스템을 검사하려는 것입니다. 이때 먼저 분석하려는 대상 시스템의 메모리 샘플을 획득하여야 합니다. 이 과정에 대한 세부적인 설명은 본 포스팅의 범위를 벗어나므로, 메모리포렌식(혜지원 역간, 원제 : The art of Memory Forensics)의 4단원을 참고하시면 좋겠습니다.


본 블로그 포스트에서 설명하는 내용들은 모두 안정적인 도구(tool)와 적절한 방법(method)을 올바르게 사용하여 획득한 메모리 샘플을 사용하는 것으로 가정합니다.


3. 플러그인 사용법

이 단원에서 보여드리고자 하는 목적은, 볼라틸리티의 플러그인중 단 3가지만을 사용함으로써, 메모리가 수집된 당시에 메모리에 적재되어 있던 실행가능한(excitable) 주요파일이나 프로그램들을 빠르게 수집할 수 있도록 하는 것입니다.


dlldump

ddldump 플러그인은 애플리케이션 실행파일이나 *각 프로세스 안에 로드된 모든 **DLL들을 추출해낼 때 사용합니다.


*숨겨진 프로세스가 있을 수 있습니다. 이 경우 활성중인 프로세스 목록(plist)에 표시되지 않고, dlldump 플러그인은 보통은 숨겨진 실행파일이나 그것이 로드한 DLL들을 추출해주지는 않습니다. 만약 숨겨진 프로세스들을 모두 찾고 싶다면 psxview 플러그인을 사용하시는 것이 좋습니다. 그런데, 사실 어떤 프로세스가 숨겨진 상태로 존재한다는 것 자체가 이미 그것은 악성(malicious)행위를 하고 있다는 것이 명백하므로 굳이 ClamScan 등을 통해 재확인할 필요까지는 없을 듯 합니다.

**DLL 역시 숨겨져 있을 수도 있습니다. 이런 경우는 다음에 설명할 malfind 플러그인을 사용하여 탐지할 수 있습니다.

위의 명령어를 보면, dlldump를 사용할 때 두가지의 옵션을 주었습니다. 첫째는 -D 입니다. 이는 executable 파일들의 덤프를 추출하여 저장할 디렉토리 위치를 지정하는 옵션입니다. 향후에 ClamScan을 사용하여 분석을 수행할 것이기 때문에, 지금부터 추출할 모든 파일들은 편의상 동일한 디렉토리 위치에 저장하도록 하겠습니다. 두번째 옵션인 --memory 는 아마 볼라틸리티 고수들에게는 익숙할 것입니다. 볼라틸리티는 기본적으로는 PE헤더에 있는 메타데이터 정보(각 section의 original size)에만 의존하는데, --memory옵션은 PE파일에 대한 모든 메모리 영역을 추출하도록 지시하는 것입니다. 이를 통해 패킹된 파일을 메모리에서 추출할 때 원본파일 뿐만 아니라 unpacked 된 파일까지 모두 얻을 수 있으므로  상당히 유용합니다.


malfind

다음으로 설명드릴 플러그인은 malfind입니다. 이 플러그인은 악성으로 의심되는 실행파일(보통은 dll들)이나 각 프로세스 내부의 쉘코드들을 검색하는 기능을 수행합니다. malfind가 구체적으로 어떠한 원리로 동작하는지에 대한 설명은 이 포스팅의 범위를 벗어나는데다가, 현재상황에서는 논외로하여도 큰 무리는 없으므로 생략하도록 하겠습니다. 더 자세한 정보는 메모리포렌식(혜지원 역간, 원제 : The art of Memory Forensics)을 참고하시기 바랍니다. 아래의 코드는 stuxnet샘플에 대한 malfind 실행 결과입니다.

기본적으로는, malfind가 검사하는 각 메모리 영역 중 의심스러운 곳에 대해 어떤 프로세스와 연결되어 있고, 영역의 시작주소와 끝주소, hex dump, 의심되는 시작지점의 디스어셈블된 바이트 코드 등등 다양한 정보들을 출력합니다. malfind에 -D 옵션을 지정하면, 원하는 디렉토리에 각 의심부분들을 별도로 분리하여 파일 형태로 저장할 수 있습니다.


malfind로 추출한 파일들에 대해 (리눅스 등에서 제공하는) file 명령어를 수행해보면, 이것이 어떤 형식의 멀웨어인지 조금 더 정보를 얻을 수 있을 것입니다.

위의 실행결과를 보면, 특히 Windows Executable 형식으로 보이는 파일들의 목록이 표시되고 있습니다. 그중의 일부는 정확히 분석이 되지 않아서 data라고만 표시되었으며 이 경우는 malfind가 해당 영역을 오탐지(false positive)한 경우이거나, 쉘코드 삽입을 발견한 경우입니다. 우리는 단지 자동화된 선별을 위하여 이 플러그인을 사용한 것이므로, 이 단계에서 이것들을 일일이 각각 조사해볼 필요없이 다음 단계로 넘어가면 되겠습니다.


moddump

지금까지 ddldump와  malfind 플러그인을 사용함으로써, 대상 시스템 메모리에 적재되어있는 executable 파일들을 획득하였습니다. 이것은 사용자가 직접 수동으로 하나하나 찾아볼 필요 없이, 볼라틸리티가 자동으로 유저영역의 프로세스 메모리를 덤프한 것입니다. 이제 마지막으로 설명드릴 플러그인은 moddump인데요, 커널 메모리로부터 executable driver들을 모두 추출해내는 것을 목적으로 합니다.

위의 볼라틸리티 명령어를 통해, 커널 메모리에서 *모든 드라이버들을 지정된 디렉토리에 추출하도록 하였습니다.


*moddump는 커널에서 추출된 각각의 모듈의 위치를 알아내기 위해 링크드 리스트 방식을 사용합니다. 그런데, 이 리스트는 치밀하게 계산된 악성코드에 의해 조작되었을 가능성도 있습니다. 따라서 리스트에는 존재하지 않는 것처럼 보이는 상황일 수도 있습니다. 심지어 해당 멀웨어와 관련있는 드라이버 파일이 없는데도 작동되기도 합니다. (볼라틸리티 전문 용어로 일명 ‘고아상태의 쓰레드(orphan threads)’) 이런 종류의 함정은 일단 논외로 하고 진행하도록 하겠습니다.


4. ClamScan으로 탐지하기

지금까지 dlldump, malfind, moddump를 사용하여 메모리에서 자동으로 executable 파일들을 찾아서 추출해내었습니다. 우리는 ‘알려진 악성코드’가 시스템에 존재하는지 확인하기 위한 용도로 ClamAV를 사용하고자 합니다. 처음 들어보시는 분들을 위해 설명하자면, ClamAV는 수백만가지의 악성코드 시그니쳐를 탑재하고 있는 오픈소스 안티 바이러스 엔진입니다. 기본적으로 커맨드라인 방식을 사용하기 때문에 자동화하기에도 편리합니다.


다음과 같이 명령어를 수행하면, 볼라틸리티의 플러그인 3개로 추출했었던 executable 파일들이 들어있는 stuxout 디렉토리에 대해 clamscan을 수행한 결과가 나타납니다.

결과물(SCAN SUMMARY)를 살펴보면, 유저 영역의 6개의 프로세스 파일들이 AV 시그니처와 일치하였음을 명확하게 파악할 수 있습니다. 뿐만 아니라, 커널 메모리에서 추출했던 드라이버 중 하나인 driver.f895a000.sys 역시 시그니처가 일치함을 알 수 있습니다. ClamScan이 간혹 오탐지(false positive)를 할 때도 있지만, 보통 다수의 파일로부터 다수의 시그니처가 탐지된 경우라면 그 시스템은 실제로 감염되어있을 가능성이 높습니다. 지금의 예제에서는 ClamAV가 스턱스넷과 관련된 몇가지 악성코드 부분들을 정확하게 식별해낸 것을 알 수 있습니다.


5. 이 방법의 장점

속도

이 방법을 수행함으로써 얻을 수 있는 유익은, 단지 3개의 플러그인만을 입력하여 사용함으로써 굉장히 빨리 처리할 수 있다는 것입니다. 해당 플러그인들은 모두 메모리 전체를 탐색하지 않는 방식으로 작동하기 때문에 각각의 작업은 1분이내의 짧은 시간으로 작업이 종료됩니다. 

단, ClamAV는 메모리 샘플로부터 추출된 파일들을 모두 처리해야하므로, 경우에 따라 보통은 1분에서 10분정도의 시간이 소요될 수 있습니다.


규모 가변성

여기에서 설명된 내용을 스크립트화하여 자동화할 수도 있고, 여기에 설명된 내용을 모두 수행하는데에는 15분도 채 걸리지 않으므로, (알려진) 악성코드를 탐지하는데에 있어서는 정말 최적의 성능을 제공합니다.


패킹 무력화

이 방법을 사용하는데 있어서 핵심적인 장점은, 메모리 포렌식을 통해 추출된 악성코드는 unpack된 형태로 남아있다는 점입니다.(가상머신 기반 패킹 등 매우 진보된 방식은 제외) 즉, 안티바이러스 엔진이 악성 파일 내용의 실체를 정확히 검사할 수 있다는 점입니다. 보통의 악성코드는 패킹이나 난독화 등의 방법으로 자신을 숨기기 마련인데, 메모리에 올라오려면 그것들이 해제된 상태로 로드되어야 하고, 따라서 Yara rule등을 사용하여 메모리를 분석하면 악성코드를 매우 쉽게 탐지가능합니다.


메모리 기반(Fileless) 멀웨어 & 코드 인젝션 대응

malfind를 사용함으로써, 메모리에 인젝션 된 코드를 발견할 수 있습니다. 디스크에 파일형태로 존재하지 않고(Fileless) 여러가지 다른 방법을 통해 삽입된 악성코드의 경우에는 일반적인 endpoint 보안 프로그램이 쉽사리 발견하지 못합니다. 


샘플 업로드 불필요

VirusTotal이나 Malwares.com 같은 업체들은 악성코드를 판별해주는 서비스를 제공하고 있습니다. 하지만 이 방법을 사용하면 로컬에서 간단한 테스트를 하는 것만으로도 동일한 효과를 얻을 수 있으므로 불필요하게 온라인에 샘플 파일을 업로드하는 번거로움을 대체할 수 있습니다.


운영체제에 대한 세부지식 불필요

여기에서 언급한 몇가지 명령어를 사용하는데에는, 별도로 엄청난 메모리 포렌식 능력이나 운영체제에 대한 깊은 지식이 요구되지 않습니다. 그저 플러그인을 사용하기 위한 명령어를 몇번 입력하고, Clamscan을 수행하기만 하면 됩니다.


6. 이 방법의 한계

이 방법이 매우 유용함에도 불구하고, 100% 완벽하다고는 보장할 수 없습니다. 그 단점에 대해 몇가지 짚고 넘어가도록 하겠습니다.


알려진 악성코드에 대해서만 가능

글의 서두에서 미리 밝혔듯이, 이 접근방법은 오직 ‘알려진’ 악성코드에 대해서만 유효합니다. 최초의 Stuxnet의 주 타겟이었던 조직인 SIEMENS가 만약 이 시스템을 도입했다하더라도, 그때에는 여기에 해당되는 시그니처가 없었으므로(최초로 발견된 사건이므로), 이를 탐지해내지 못했었을 것입니다.

그러므로 여기에서 설명한 방법은 멀웨어에 대한 해박한 지식이나 시그니처를 모르더라도 손쉽게 ‘알려진 악성코드'를 탐지하고자 하는 것을 목적으로 한 것입니다. 볼라틸리티 프레임워크의 핵심 개발자인 Michael Ligh 의 블로그에서는 스턱스넷의 사례에서 볼라틸리티를 사용하여 효과적으로 이상(anomaly)을 탐지하는 보다 일반적인 방법을 설명하는 내용이 실려있습니다. (*역자 주 : Prezi로 작성된 프리젠테이션 페이지입니다.)


모든 항목을 다 매핑할수는 없다

이 방법의 두번째 단점은, 메모리를 수집할 당시에 하필이면 해당 악성코드가 상주하고 있지 않은 시점일수도 있다는 것입니다. 아직 파일의 형태로 디스크에 적재되어 있거나, 메모리 페이지 파일의 형태로 흩어져 있을 수도 있습니다. 이러한 경우라면 악성코드의 존재여부를 찾기 위해서 조금 더 심층적인 분석을 수행해야만 합니다.


ClamAV는 완벽하지 않다

세상에 ‘완벽’하다고 자신있게 단언할 수 있는 보안 툴은 없습니다. ClamAV 역시 마찬가지입니다. ClamAV가 분석한 executable 파일들에 대해 ‘이상없음’이라는 응답을 준다 하더라도, 그것이 진짜로 적법한(legitimate) 행위를 하는 프로세스라고 무조건 맹신해서는 안됩니다. ClamAV을 통해 이미 알려져있는 악성코드를 빠른 시간안에 찾기위한 목적으로 이용하는 것이지, 해당 시스템에 멀웨어가 없으므로 안심해도 된다는 근거로 사용해서는 안됩니다.


7. 주의사항

여기에서 언급한 방법을 여러분의 시스템 환경에 적용하기 전에, 다음 두가지 주의사항을 명심하십시오.


ClamAV의 버그

불행하게도, ClamAV 프로그램은 형식안전(type-safety) 방식을 따르는 프로그래밍 언어를 채택하지 않았습니다. 그러므로 취약점이 존재합니다. 만약 악성코드 샘플이 이러한 취약점을 악용한 코드를 내장하고 있다면, ClamAV 엔진이 해당 파일을 스캔할 때 익스플로잇(Exploit) 시킬 수 있습니다. 이는 ClamAV 뿐만 아니라 상당수의 anti-virus 프로그램이 동일하게 겪는 문제이므로 유의해야 합니다. 해당 엔진들 모두 상당한 익스플로잇 버그 리포트를 보유하고 있으며 적절한 패치를 꼭 수행하시기 바랍니다. 어쨌든 이러한 이유로, 악성코드 분석을 수행하려는 시스템에는 절대로 중요한 데이터를 보관해서는 안되고, 네트워크가 분리된 가상 시스템(Virtual Machine)에서 수행하시기 바랍니다. 


윈도우 시스템이나 가상머신 공유폴더

만약 이 방법을 보통의 윈도우 시스템에서 수행하려하거나, 혹은 가상머신 안의 공유폴더에 대해 처리하고자 할 때에 로컬 호스트에 별도의 백신 프로그램이 작동하고 있는지 반드시 확인해야 합니다. 이 경우 여러분이 분석하고자하여 추출해둔 파일을 백신프로그램이 미리 발견하고 임의대로 삭제하거나 격리시켜버릴 가능성이 있습니다. 그러면 여러분이 의도한 ClamScan 과정에서는 해당 파일이 이미 치료(또는 삭제)되었으므로 그 파일을 악성인 것으로 표시할 수가 없게되고, 조사관은 잘못된 판단을 하게 될 것입니다.


8. 질문과 답변

dumpfiles 플러그인을 쓰는 것은 어떤가요?

볼라틸리티 사용경험이 있으신 분들이라면, 이 과정에서 dumpfiles라는 플러그인을 사용하는 것이 더 편리하지 않느냐는 의문을 가지실 수 있습니다. 물론 dumpfiles는 메모리로부터 스스로 executable 파일이나 캐쉬 파일을 복구하는 기능을 탑재하고 있기에 유용하며 사용하셔도 되긴합니다. 그러나 다음의 유의사항을 기억하십시오.

  • dumpfiles를 사용할 경우 결과물 디렉토리의 용량이 매우 커짐.
  • dumpfiles의 결과물인 cache에는 디스크로부터 추출한 파일 콘텐츠가 포함되어 있습니다. 이미 앞에서 unpacked까지 완료된 파일을 메모리에서 획득하였는데, 굳이 packed되어있을 파일까지 중복해서 얻어낼 필요는 없습니다.
  • dumpfiles는 보통 가능한 ‘모든’파일을 찾아서 덤프하기 때문에, 위에서 언급한 3개의 플러그인에 비해 실행시간이 매우 느립니다.


결론적으로, dumpfiles를 절대로 사용하지 말라는 뜻은 아닙니다만, 꼭 필요한 경우 그 사용에 대해 감수해야할 사항들이 있다는 점을 기억하시기 바랍니다.


9. Linux & macOS

여기에서 언급한 것과 동일한 플러그인이 Linux나 macOS 시스템에서도 제공되며, stuxnet sample에 문제없이 적용됩니다. 보다 자세한 사항은 Volatility Cheat Sheet를 참고하세요.


10. 결론

지금까지 본 포스팅에서는 메모리 샘플만 있으면 즉각 귀하의 시스템에 적용해 볼 수 있는 방법을 제시하였습니다. 본 내용에 대한 추가적인 질문사항이 있으시면, 자유롭게 아래로 연락주시기 바랍니다.

E-mail : andrew @@@ AT @@@@ dfir.org 

PGP : https://pgp.mit.edu/pks/lookup?op=get&search=0xBC6384A9B2446B45

Twitter : @attrc 또는 @volatility


번역자 첨언

개인적으로, 어색하게 직역되어 무슨뜻인지 이해가 불가능한 글을 상당히 싫어합니다. 이 글은 제가 원문의 글을 파악하고 이해한 후에 그 문장을 익숙한 한국어 문장으로 다시 작성하였습니다. 따라서 이 글의 번역은 단순한 직역이 아니라, 역동적 대응(Dynamic equivalent) 번역입니다. 원문의 의도가 왜곡되었다고 느껴지는 부분이 있다면 cpuu@kaist.ac.kr로 언제든지 문의주시기바랍니다.

CPUU님의 창작활동을 응원하고 싶으세요?