본 포스팅의 원문출처는 Cisco Security Blog이며, 2017년 2월 2일에 게시된 원문 글의 제목은 Malware Analysis for the Incident Responder 입니다. 해당 블로그의 글을 번역하여 포스팅합니다. 


악성코드(Malware)는 가장 교활한 형태의 사이버 공격 중 하나이며, 그 파급효과 또한 상당합니다. 그들을 일일이 찾아 식별하고 제거하는 것만이 위협을 최소화할 수 있는 핵심 방안입니다. 저는 침해사고 분석가로 종사해왔으며 악성 파일을 분석하는 역할을 감당하고 있습니다. 본 포스팅에서는 제가 소속된 침해사고 대응팀에서 주로 사용하는 실전적인 노하우를 전수해드리고자 합니다.


의심스러운 파일들을 세세하게 분석하여 잠재적인 악성코드를 찾아낼 때 여유로운 시간이 주어지는 경우는 거의 없습니다. 실제로 한 파일에 대해 리버스 엔지니어링을 수행할 때에 적게는 몇 주에서 길게는 몇달까지 걸릴수도 있습니다. 또한, 분석가 개개인의 능력에 따라 편차가 상당히 크기 때문에 소수의 고수들에게 일이 집중되는 등의 어려움이 존재합니다. 따라서 침해사고 대응 절차상의 각 단계별로 신속히 파악하기 위해서는 적절한 침해사고 대응 지표(indicator)에 대해 논의할 필요가 있습니다. 이러한 일련의 지침을 직접 구상하고 이해하는 과정을 통해 저희 팀은 긴급한 상황에서 리버스 엔지니어링이 완료되기를 하염없이 기다리기보다는, 재빨리 대응전략을 수립하고 시행하는데 더 집중할 수 있었습니다.


Lenny Zeltser는 악성코드 분석 과정을 4단계로 구분지어 설명하였습니다. 가장 먼저 제일 쉬운 방법인 ‘완전 자동화’ 프로그램을 사용하여 분석을 첫번째로 수행하고, 그 다음에는 정적(Static) 속성을 분석합니다. 이후에는 행위(Behavior)를 찬찬히 뜯어본 후에, 최종적으로 전체 코드를 직접 수작업으로 리버싱하는 과정을 거칩니다. 완전 자동화 분석에는 ThreatGrid와 같은 도구들이 유명하며 아마 여러분도 사용해보신 적이 있을거라 생각합니다. 이러한 유형의 툴들은 신속한 보고서를 제출해주지만, 분석가의 의도를 완벽히 헤아려 그 입맛에 맞는 해답을 주지는 못합니다. 따라서 그 결과물은 사용하기 쉽지만 그저 분석가를 돕기위한 도구의 일부일 뿐이라는 한계가 명확합니다. 결국 의심스러운 파일을 구체적으로 분석하는 것은 여전히 사람의 몫입니다.


Lenny Zeltser가 제시한 악성코드 분석의 4가지 단계. 상위로 갈수록 난이도가 어려워진다.
Lenny Zeltser가 제시한 악성코드 분석의 4가지 단계. 상위로 갈수록 난이도가 어려워진다.

침해사고 대응 업무에 있어서 능률높은 성과(Efficiency)와 성공적인 효율(Effectiveness)을 끌어올리것을 목표로 합니다. 침해사고 대응에서 가장 핵심적인 목적인 문제의 근본 원인을 파악하고 궁극적으로 장애복구를 성공적으로 완수하는 데 있습니다. 따라서 그 상황에서의 취약점 하나하나를 모두 찾고 그 복잡한 코드들을 완벽히 이해하기 위해 안간힘을 쓰며 연구하는 방식으로 접근하면 안됩니다. 우선은 발등에 떨어진 불부터 먼저 끄고나서, 이후 여유를 갖고 추가적이고 심층적인 연구를 수행하면 됩니다. 저는 Vilfredo Pareto가 경제학 분야에서 고안한 파레토(Pareto) 원칙(*역주 : 일명 80-20 rule으로, 전체 결과의 80%가 전체 원인의 20%에서 일어나는 현상을 가리킨다.)이 침해사고 대응 상황시 악성코드 분석에도 동일하게 적용된다고 생각합니다. 악성코드 분석의 20%를 통해 나머지 80%도 가늠할 수 있으며 이는 결국 사고상황의 전체적인 큰 맥락을 이해하고 적절한 전략을 세움으로써 성공적인 마무리를 할 수 있도록 이끕니다. 따라서, 굳이 모든 코드 전체를 수동으로 하나하나 까뒤집으며 악의적인 파일이 무슨짓을 하는지 그리고 그 샘플들에 대한 시그니처를 어떻게 추출할 것인지 항상 고민할 필요는 없습니다. 


저희는 침해사고 대응을 위한 악성코드 분석을 수행할 때 아래와 같은 다양한 도구들을 주로 활용합니다. 저희 팀 모두가 이것들을 잘 다루고 있으며, 구체적인 사용예시도 영상으로 보여드리도록 하겠습니다.


정적 분석(Static Property Analysis)

정적 분석을 할 때 제가 가장 유용하게 사용하는 도구는 Marc Ochsenmeier가 개발한 pestudio입니다. 이에대한 더 자세한 설명이 필요하신 분은, 제가 몇달전에 따로 작성해둔 개인 블로그를 참고해주시면 되겠습니다. 정적 분석을 할 때에는 보통 해쉬값을 계산한 후 검색엔진이나 악성코드 관련 사이트에 질의를 보냅니다. 그리고 파일에서 문자열(Strings) 정보를 추출하여 그 목록을 살펴봅니다. 문자열 검색만으로도 해당 파일의 행위를 예측해볼 수 있는 정보를 상당히 얻을 수 있습니다. 해당 파일이 난독화(Obfuscation)만 되어있지 않다면, 그 파일에 포함된  DNS 정보, IP 주소, 데이터가 저장될 디렉토리 경로 등이 평문으로 남아있을 것입니다.


또한, 해당 파일이 임포트한 함수들을 조사하는 것도 추후 이루어질 동적 분석 단계에서 어떤 파일들을 더 살펴보아야 하는지를 예상하고 결정하는 데 큰 도움이 됩니다. 예를들어 윈도우 작동하는 응용 프로그램이나, 기타 다른 운영체제이건 그것들은 반드시 API(Application Programming Interface)을 통한 다양한 funtion들을 임포트하고 있을 것입니다. 이러한 import들을 조사함으로써 그 악성코드가 하려는 행위를 파악할 수 있습니다. 만약 윈도우의 레지스트리를 기록하는 함수가 사용되고 있다면 이는 곧 레지스트리 변조를 목적으로 하는 프로그램이라는 것을 알려주는 것입니다. 나아가 정확히 어떤 레지스트리 키가 변경되고 있는지를 일전에 덤프해둔 문자열 정보와 종합하여 찾아낼 수도 있습니다. pestudio는 import된 함수들 중 특히 악성코드들이 주로 사용하는 것들을 블랙리스트로 구분하여 강조(Highlight) 표시를 해주는 기능을 제공합니다. 


그 다음으로는 파일에 대한 정적분석을 기반으로 하여 고유의 시그니쳐를 생성합니다. 해당 파일의 시그니처가 백신 프로그램이나 침입 탐지/차단 시스템의 정책에 지명수배가 되어있는지를 검사하는 것인데, 보통은 Hash값을 기반으로 간단하게 검사합니다만 최근의 악성코드들은 자가변조 등의 방법으로 해쉬값을 계속해서 바꿔버리기 때문에 그닥 좋은 방법은 아닙니다. 때문에 바이트 형태의 문자열이나, 사람이 읽을 수 있는 문자열을 기반으로 생성한 시그니쳐를 생성하는 것이 권장됩니다.

pestudio 8.54.버전
pestudio 8.54.버전


동적 분석(Interactive Behavior Analysis)

대부분의 악성코드들은 정적 분석을 피하기 위해 난독화기법을 사용합니다. 일부러 복잡한 함수들을 이리저리 숨기고 섞어놓음으로써 분석가를 고통스럽게하고 해독이 어렵도록 하기 위함입니다. 동적 분석은 발견된 해당 악성코드를 특정한 실험환경에서 직접 실행해보고 어떠한 변화가 일어나는지를 관찰하는 방법으로 자세한 정보들을 수집하는 것입니다. 이는 자동화분석과 유사하지만, 약간의 차이점이 있다면 동적분석에서는 악성코드가 실행된 상태에 직접 접근할 수 있다는 것입니다. 이를 수행하기 위해서는 고의로 악성코드에 감염시킬만한 실험환경을 구축하는 것이 선행되어야 합니다. 예를 들면, 해당 악성코드가 Java와 관련된 취약점을 유발하는 것으로 보일 때 그와 호환되는 취약한 버전의 Java가 설치된 가상머신을 일종의 실험쥐로 준비하여야 합니다.


악성코드가 취약한 호스트 컴퓨터에서 실행되는 동안 분석가는 해당 시스템이 어떤 변화를 보이는지 유심히 관찰합니다. 악성코드는 분명 지속성(Persistent)를 갖기 위한 모종의 술수를 꾀할 것이고, 이에 따라 어떤식으로든 호스트를 변조할 수밖에 없습니다. 그 과정에서 일어나는 여러가지 동작이나 통신패킷 등을 캡쳐한다면, 이 악성코드로부터 피해를 입은 다른 시스템에서도 동일한 일이 벌어졌음을 알수있게 됩니다.


악성코드를 실행하기 전에, 이를 적절하게 통제할 수 있는 특수한 실험환경을 구축해야한다고 했습니다. 윈도우용 악성 바이너리 파일들은 대부분 32bit의 Intel x86아키텍처에서 컴파일 된 윈도우7 서비스팩0을 이용하면 무난하게 해결할 수 있습니다. 이 시스템은 최대한 악성코드의 활동을 보장하기 위해 되도록이면 보안패치를 수행하지 않고 내버려두는 것이 좋습니다. 만약 다른 종류의 버전을 사용하거나 프로세서 또는 운영체제가 다른 경우라면, 그에 알맞는 실험환경으로 재구축할 필요가 있습니다. 이러한 정보는 정적분석에서 수행했던 결과를 토대로 파악할 수 있습니다.


악성코드가 네트워크 통신을 하려는 것을 감시하기 위한 적당한 함정을 마련하는 것도 중요한데, 저희는 이 때 INetSim을 사용합니다. 이것은 리눅스용 프로그램이며, SANS 연구소에서 개발한 REMnux 배포판에 설치되어 있습니다. 다른 리눅스 배포판에서도 직접 설치하는 것이 가능합니다.


분석에 필요한 모든 기능을 활성화하기 위해서는 반드시 INetSim의 환경설정을 살펴보아야 합니다. 기본적으로 대부분의 기능이 비활성화되어 있으며, 원하는 기능에 한해서 직접 코멘트(주석처리)를 해제해주어야 합니다. 관련된 구성을 잘 검토하고 필요에 따라 적절히 수정하는 것을 권장합니다.

INetSim을 실행한 화면
INetSim을 실행한 화면
INetSim 환경설정 화면
INetSim 환경설정 화면

악성코드 샘플을 실행하기에 앞서, 이것의 행위를 감시하기 위한 도구를 먼저 작동시켜야 합니다. 대표적으로 두가지 툴을 사용하고 있는데, SysInternal의 Process Monitor는 시스템 전체의 변경사항(레지스트리, API 후킹을 통한 파일시스템 접근 등)을 관찰하기 위한 용도로 적격입니다. 해당 프로세스가 파일 시스템에 쓰기작업을 수행한다면, 이와 관련된 Windows API를 호출할 수밖에 없다는 점에 착안하여 프로세스 모니터가 이러한 상황을 인지하고 해당 Call을 추적하여 어떤 인자들이 전달되었는지, 그 Call을 요청한 객체가 무엇인지를 찾아냅니다. 또한 해당 프로세스와 쓰레드에 대한 자세한 정보를 테이블 형태로 정리하여 보여주는데 실시간 변경사항을 지속적으로 업데이트해줍니다. 그리고 이 정보들을 CSV(Comma Separated Value) 파일 포맷으로 저장하여 추후에 보고서에 첨부할 용도로 활용하는 기능도 제공합니다. 특히 다른 도구에서 활용가능하도록 추출하는 방법도 있는데, 추후에 알려드릴 ProcDOT라는 도구에 적합한 형태로 출력하기 위해서는 아래 그림과 같이 체크박스를 선택해야 합니다.

ProcMon을 실행한 화면
ProcMon을 실행한 화면
ProcMon 환경설정 체크리스트
ProcMon 환경설정 체크리스트

악성코드들은 네트워크 통신 역시 수행하는 경우가 많습니다. 이러한 패킷들을 캡쳐하기 위해서는, 널리 알려진 Wireshark(와이어샤크)를 활용하면 됩니다. 윈도우 7에서도 지원 가능합니다. INetSim을 먼저 작동시킨 후 Linux와 윈도우 호스트 사이에 통신이 이루어지도록 먼저 설정을 해두십시오.


그리고 악성코드가 원래 자신이 의도하였던 C&C 서버로 통신하게 하는 것이 아니라(그렇게 되면 또한번의 침해사고가 발생하는 것입니다), 이와 비슷한 환경으로 구성해놓은 일종의 함정으로 유인하도록 하는 것입니다. 그렇게 함으로써 와이어샤크에 잡힌 패킷들의 정보를 통해 분석의 단계를 고도화할 수 있습니다.

Wireshark를 실행한 화면
Wireshark를 실행한 화면

이제 Wireshark와 Process Monitor만을 통해서도 다양한 악성코드 샘플을 테스트해 볼 수 있습니다. 해당 파일을 관리자권한을 사용하여 실행한다면 호스트에 미치는 영향이 가장 크겠지만 현실적으로 어려움이 존재할 수 있습니다. 때문에 다양한 수준의 권한을 가진 계정 몇개를 사용해서 샘플을 실행해보고 어떤 결과가 나타나는지 확인해보는 것이 일반적입니다. 샘플들의 작동으로 발생한 결과물들은 Task Manager나 Process Explorer로 관찰할 수 있습니다. 악성코드의 핵심적인 기능들이 대부분 재연되었다고 판단되면, 캡쳐를 중단하고 관련 자료들을 뽑아냅시다.


추출된 데이터들을 멋지게 시각화할 수 있는 ProcDOT 프로그램으로 로드해봅시다. 이를 위해서는 ProcDOT에서 요구하는 형식에 맞게 WireShark나 Process Monitor의 결과물이 잘 정리되어 있는지 점검해야 합니다. 오류가 없다면 ProcDOT은 현재 실행중인 악성 프로세스와 관련하여 직관적인 그래프를 그려줍니다. 그래프를 확인해보면 어떤 레지스트리가 생성되었고, 파일시스템에 파일이 추가되었거나, 네트워크 통신을 위해 DNS 정보를 확인했는지 한눈에 파악할 수 있도록 일목요연하게 정리되어 있음을 볼 수 있습니다.

ProcDOT 결과물의 스크린샷
ProcDOT 결과물의 스크린샷


결론

지금까지 이토록 악성코드를 분석한 이유는 결국 해당 제품에서 악성코드가 실제로 작동되었는지를 판단할 지표(Indicator), 즉 아티팩트를 결정하기 위함입니다. 이러한 지표들은 엔터프라이스 SIEM(Security Information and Event management)을 사용하거나, Yara, OpenIOC, Snort 등의 Rule을 통해서 산정할 수 있습니다.


본 포스팅에서 설명한 방법에도 몇가지 제약사항이 있습니다. 악성코드는 자신이 실행되고 있는 환경이 가상머신(VM)인지 알아챌 수도 있습니다. 이러한 문제를 방지하기 위해서는 정적 분석시 악성코드가 해당 기능을 가지고 있는지 먼저 파악한 후 탐지 메커니즘을 제거하거나, 다음 절차를 적절히 조절하는 등의 조치를 취해야 합니다. 만약 가상화 환경에서 악성코드가 작동되지 않도록 설정되어 있다면, 해당 서브루틴을 NOP으로 패치하여 건너뛰도록 하거나, 실제 물리적으로 구축된 실험환경에서 테스트하는 방법을 사용하십시오.


악성코드를 분석하기 위한 방법을 간단히 소개해드렸습니다. 그럼에도 불구하고 침해사고 분석가가 포렌식 수사를 수행하는 동안 발생하는 예상치 못한 일들로 인해 그 어려움은 몇배나 더 어려워질 수도 있습니다. 어쨌든, 악성코드 전체를 리버스 엔지니어링을 하기보다는, 핵심적인 요소들을 침해지표로 선정하고 관련 절차에 따라 신속한 침해사고 대응을 수행하도록 권합니다. Cisco의 Security팀이 제공하는 침해사고 대응 서비스(Incident Response Service)는 고객이 보유하고 계신 의심 파일들에 대해 심층적인 분석을 수행해드리고 있습니다. 이와 관련하여 Talos Intelligence와의 파트너쉽도 체결하였습니다.


본 포스팅에서 설명드린 ‘악성코드 분석을 위한 도구들’에 대한 시연 영상을 아래 Youtube 링크로 제공드리오니 많은 참고 바랍니다.


#침해사고대응 #동적분석 #정적분석 #악성코드분석

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