on
악성코드 동적 분석 시스템 탐지 기법(Bypass dynamic malware analysis system)
1. 서론
동적 분석 시스템은 시그니처 기반 보안 제품만 사용할 때 간지러운 부분을 긁어주는 역할을 한다. 동적 분석 시스템은 악성 유무가 판단되지 않는 파일을 샌드박싱된 공간에 넣어 구동시키고 그 행위를 모니터링하고 로깅한다. 상용 시스템의 경우에는 각 과정에서 발생하는 행위를 분석하여 의심가는 행동에 대해 점수를 매긴다. 점수는 각 시스템마다 별개의 스코어링 기법(Scoring Scheme)을 사용한다. 동적 분석 시스템은 별도의 시스템으로 존재하기도 하지만, 몇몇 안티 바이러스에 내장되어 애플리케이션 실행 시점에 바이너리를 검증하기도 한다.
이러한 동적 분석 시스템이 기업이나 공공기간에 도입되면서, 공격자들은 동적 분석 시스템을 탐지하여, 실제 시스템과 다른 행동을 하는 기능을 악성코드에 넣기 시작하였다. 본 포스팅에서는 분석가가 알아두면 좋을만한 악성코드의 탐지 방법을 논하겠다. 여기에 작성한 기법은 고도의 기술을 적용한건 아니지만 상당히 효과적인 방법이며 실제로 마지막 탐지 방법을 제외한 모든 기능은 'Operation SNOWGLOBE'에 사용되었다.
참고로 기존에 잘 알려진 가상머신(Virtual Machine) 탐지 기법(SIDT, IO Instruction)에 대한 내용은 인터넷에 많이 정리되어 있으니 본 글에서는 다루지 않는다.
2. 시스템 탐지 기법
2.1 자기자신의 이름으로 판단 (AV 동적 분석 탐지)
동적 분석 기능이 내장된 안티바이러스 제품군은 신뢰되지 않은 실행 파일이 실행되면, 샌드박싱 시스템에서 테스트를 거친 다음에 문제 없는 바이너리로 판단되면, 다시 정상적으로 실행한다. 여기서 재미있는 점은 각 안티바이러스 제품은 샌드박싱에 해당 실행 파일을 로드할 때 실행 파일의 이름을 변경한다는 점이다. 예를 들어, 비트디펜더(BitDefender) 같은 경우는 “TESTAPP”이라는 이름을 가지며, 카스퍼스키의 경우엔 “afyjevmv.exe”, “lstcvix.exe”, “tudib.exe”, “izmdmv.exe” 등을 사용한다 [1]. 악성코드는 이 점을 이용하여 자신이 구동될 때 자기자신의 파일 이름을 확인함으로 동적 분석 상태인지 확인할 수 있다. 다음과 같은 코드로 작성된다.
// pseudo code
Path = GetModuleFileName();
Filename = _splitpath(Path);
if strstr(Filename, "klaveme") is not NULL:
exit(1);
elif strstr(Filename, "myapp") is not NULL:
exit(1);
elif strstr(Filename, "TESTAPP") is not NULL:
exit(1);
elif strstr(Filename, "afyjevmv.exe") is not NULL:
exit(1);
else: // is NULL
// 작업 진행
2.2 프로세스 갯수 기반 탐지 (가상화 기반 동적 분석 탐지)
프로세스 갯수 기반 탐지는 가장 쉽게 시스템을 판단할 수 있는 방법이다. 보통 사용자가 운영체제를 설치하면, 단순히 운영체제만 구동하는 것이 아니라 안티바이러스, 클라우드 스토리지 프로그램, 클라우드 노트 프로그램, 메신저 등 다양한 프로그램이 운영체제에서 돌아가게 된다. 이 점을 악성코드가 이용하면 동적 분석 환경임을 쉽게 인지할 수 있다. 예를 들어 ‘SNOWGLOBE 작전’에 사용된 악성코드는 현재 시스템의 프로세스가 15개 미만이라면, 아무런 행위를 하지 않고 종료한다.
EnumProcesses(ProcessIDs, cbsize, cbsizereturned);
ProcessCount = cbsizereturned/4;
if ProcessCount < 0x0F:
exit(1);
else:
// 작업 진행
2.3 페이로드를 자동 실행에만 등록
동적 분석 시스템은 바이너리 샘플을 로드하면, 로드한 샘플이 실행하는 프로세스에 대해서도 분석을 진행한다. 최근 DBD을 통한 드롭퍼를 다운로드하여 페이로드를 실행하는 경우도 많다보니 동적 분석 시스템의 기본 기능이 되었다. 드롭퍼 형태의 악성코드를 보면 드롭퍼 자체는 페이로드를 다운로드/익스포트하고 페이로드가 실행되도록 환경을 구성하는 기능만을 가지고 있으며, 대부분의 악성 행위는 페이로드에서 실행된다. 즉 연관되는 프로세스까지 분석해야지 해당 샘플의 악성유무를 판단할 수 있다. 악성코드는 이점을 역 이용하여 드롭퍼가 페이로드를 자동 실행에 등록’만’ 하는 방법을 사용한다. 보통은 드롭퍼가 페이로드를 자동 실행되도록하고 페이로드가 실행 후 자기자신을 지우는 것이 일반적이나, 페이로드를 재부팅 시 실행되도록하면 분석 시스템은 드롭퍼만 분석하고 끝내게 된다. 단 이 방법은 공공기관과 같이 하루 한번 시스템을 껐다가 키는 환경에 적합하다.
2.4 Time distortion (시간 왜곡)(AV 동적 분석 탐지)
안티바이러스 제품군이 악성코드를 동적 분석 기능은 실행 이벤트를 받았을 때 수행되므로, 최대한 적은 시간을 소모하는 것이 좋다. 그러다보니 제한시간을 두고 분석을 할 수 밖에 없게되는데, 이 경우 악성코드가 길게(라고 해봤자 3분?) 슬립한다면 제대로 분석할 수 없게 된다. 이러한 문제를 해결하기 위해 몇 가지 트릭을 사용하는데 가장 좋은 방법이 Sleep 이벤트에 대해서 에뮬레이션(emulation)을 통해 예정 시간보다 빠르게 다음 명령어를 실행하는 것이다. 악성코드는 이러한 특징을 역이용하여 동적 분석 환경인지를 식별할 수 있다. 방법은 생각보다 간단하다. 클럭/시간 정보를 가져오는 함수를 두 번 호출하고 그 사이에 일정시간 Sleep하게 만들어 두 번 호출한 함수간의 차이 값을 비교하는 방법이다. 말로 설명하면 이해가 안갈 듯하여 그림을 하나 첨부한다.
위 그림의 경우, GetTickCount API를 호출하고 값을 저장한다. 그리고 Sleep API에 1000(ms)을 주어 1초 동안 대기하고, 다시 GetTickCount API를 호출하여 값을 저장한다. 그리고 두 CPU Count(TickCount)의 차이를 구한다. 정상적인 시스템이라면 1000(ms)이상 차이가 발생한다. 하지만, AV 동적 분석 환경이라면, 에뮬레이션에 의해 Sleep이 정해진 CPU Count에 비해 따르게 리턴되어 다음 명령어가 실행되므로, 1000보다 낮은 TickCount을 가질 수 있게 된다. 악성코드는 이 방법으로 간단하게 동적 분석을 탐지하고 의도치 않은 행동을 할 수 있게 된다.
2.5 후킹 탐지(Cuckoo Sandbox)
후킹 탐지 방법은 가상화 기반 동적 분석 시스템에 유용할 수 있는 방법으로, 루트킷 탐지 소프트웨어처럼 시스템의 특정 API가 후킹되어있는지 확인하는 방법이다. 오픈소스 동적 분석 시스템으로 잘 알려진 ‘Cuckoo Sandbox(이하 쿠쿠샌드박스)’는 특정 함수의 프롤로그(prologue) 영역에 JMP 코드를 삽입하여 자신이 원하는 행동을 수행하는 ‘detour’ 기법을 사용한다. 악성코드 개발자는 몇몇 함수의 프롤로그를 검증하므로 ‘Cuckoo Sandbox’ 환경인지 유추할 수 있다.
(FARPROC &)pIsDebuggerPresent = (FARPROC)GetProcAddress(hwnd, "IsDebuggerPresent");
printf("CODE : %x %x %x %xn", *((PBYTE)pIsDebuggerPresent), *((PBYTE)pIsDebuggerPresent+1), *((PBYTE)pIsDebuggerPresent+2), *((PBYTE)pIsDebuggerPresent+3));
if(*(PBYTE)pIsDebuggerPresent == 0xE9) // JMP Opcode
{
printf("Function is hookedn");
}
예를 들어, 위와 같은 코드를 구동하면, Cuckoo는 다음과 같은 결과를 보여준다.
3. 결론
동적 분석 환경을 탐지하기 위한 몇 가지 트릭을 알아보았다. 읽어보면 알겠지만 악성코드는 동적 분석 시스템을 역공학 또는 테스트함으로 단순한 트릭으로 시스템을 감지/우회하고 있다. 하지만 동적 분석 시스템이 의미가 없다는 것은 아니다. 동적 분석 시스템은 시그니처 기반의 기존 탐지체계의 가려운 부분을 긁어주는 훌륭한 시스템이다. 단지 기업 내 보안 담당자분들에게는 동적 시스템에 너무 많은 신뢰를 줌으로써 큰 실수를 범하지 않길 바랐으며, 분석가에게는 이러한 트릭도 있으니 앞으로 발생하는 침해사고에서 참고하길 바랄 뿐이다.
4. Reference
[1] Cyphort, SyScan 15, Shooting Elephants, 2015.