정적 분석 static analysis은 의심스러운 파일을 실행하지 않고 분석하는 기법이다
의심스러운 바이너리에서 유용한 정보를 추출해 어떻게 분류 또는 분석할지와 이후 분석의 초점을 어디에 둘지를 결정하기 위한 초기 분석 방법이다.
1. 파일 유형 파악
분석할 때 의심스러운 바이너리의 파일 유형을 구분하는 것은 악성코드의 목표 운영 시스템(윈도우, 리눅스 등)과 아키텍처(32비트 또는 64비트 플랫폼)를 식별하는 데 도움이 된다. 예를 들어, 의심스러운 바이너리가 윈도우 실행 파일(.exe, .dll, .sys, .drv, .com, ocx 등)을 위한 파일 포맷인 PE(Portable Executable) 파일 유형이라면 해당 파일은 윈도우 운영 시스템을 대상으로 디자인 됐다는 사실을 추정할 수 있다.
하지만 파일 확장자는 파일 유형의 유일한 식별자가 아니다. 공격자는 다른 속임수로 파일 확장자를 수정해 파일을 숨기거나 유저가 해당 파일을 실행하도록 속이고자 외형을 바꾼다. 파일 확장자 대신 파일 시그니처를 이용해 파일 유형을 구분할 수 있다.
파일 시그니처는 파일 헤더에 작성되는 바이트의 독특한 배열 순서다. 서로 다른 파일들은 다른 시그니처를 가지므로 이를 파일 유형을 식별하는 데 사용할 수 있다. 윈도우 실행 파일 또는 PE 파일은 파일의 첫 바이트에 MZ 또는 헥사 문자 4D 5A 라는 파일 시그니처를 가진다.
1.1 수작업을 통한 파일 유형 식별
수작업으로 파일 유형을 구분하는 방법은 헥사 편집기로 파일을 열어 파일 시그니처를 찾는 것이다. 헥사 편집기는 파일의 각 바이트를 관찰할 수 있는 도구다. 헥사 편집기 대부분은 파일 분석에 도움을 주는 여러 기능을 제공한다.

리눅스에서 파일 시그니처를 찾고자 한다면 xxd 명령어를 사용할 수 있다.
$ xxd -g 1 log.exe | more
1.2 도구를 이용한 파일 유형 식별
파일 유형을 구분하는 다른 편리한 방법은 파일 식별 도구를 사용하는 것이다. 리눅스 시스템에서는 file 유틸리티를 이용해 파일을 식별할 수 있다. 다음 예에서 file 명령어가 2개의 다른 파일에 실행됐다. 결과를 보면 첫 번째 파일에 확장자가 없음에도 불구하고 32비트 실행 파일(PE32)이라는 것과 두 번째 파일은 64비트(PE32+) 실행 파일이란 사실을 보여 준다.
$ file mini
mini: PE32 executable (GUI) Intel 80386, for MS Windows
$ file notepad.exe
notepad.exe: PE32+ executable (GUI) x86-64, for MS Windows
윈도우에선 익스플로러 스위트에 포함된 CFF Explorer를 이용해 파일 유형을 구분할 수 있다. 비단 파일 유형을 구분하는 것에만 제한되지 않는다. 실행 파일(32비트와 64비트)을 조사하는 유용한 도구이며, PE 내부 구조를 검사하고 필드를 수정하거나 리소스를 추출할 수 있다.
1.3 파이썬을 이용한 파일 유형 구분
파이썬에서 python-magic 모듈을 이용해 파일 유형을 구분할 수 있다.
$ python
Python 2.7.12 (default, Nov 19 2016, 06:48:10)
>>> import magic
>>> m = magic.open(magic.MAGIC_NONE)
>>> m.load()
>>> ftype - m.file(r'log.exe')
>>> print ftype
PE32 executable (GUI) Intel 80386, for MS Windows
2. 악성코드 식별
식별(Fingerprinting)하기는 의심스러운 바이너리의 내용을 바탕으로 암호 해시 값 을 생성하는 활동을 포함한다. MD5, SHA1, SHA256 같은 암호 해시 알고리즘은 악성코드 샘플의 파일 해시를 생성할 때 사실상 표준으로 생각된다.
2.1 도구를 이용한 암호 해시 생성
리눅스에서는 md5sum, sha256sum, sha1sum 도구를 이용해 파일 해시를 생성할 수 있다.
$ md5sum log.exe
6e4e030fbd2ee786e1b6b758d5897316 log.exe
$ sha256 log.exe
01636faaae739655bf88b39d21834b7dac923386d2b52efb4142cb278061f97f log.exe
$ sha1sum log.exe
625644bacf83a889038e4a283d29204edc0e9b65 log.exe
2.2 파이썬에서 암호 해시 파악
파이썬에서는 다음과 같이 hashlib 모듈을 이용해 파일 해시를 생성할 수 있다.
$ python
Python 2.7.12 (default, Nov 19 2016, 06:48:10)
>>> import hashlib
>>> content = open(r"log.exe","rb").read()
>>> print hashlib.md5(content).hexdigest()
6e4e030fbd2ee786e1b6b758d5897316
>>> print hashlib.sha256(content).hexdigest()
01636faaae739655bf88b39d21834b7dac923386d2b52efb4142cb278061f97f
>>> print hashlib.sha1(content).hexdigest()
625644bacf83a889038e4a283d29204edc0e9b65
3. 다중 백신 스캐닝
의심스러운 바이너리를 다중 백신 스캐너로 스캐닝하면 의심스러운 파일에 악성코드 시그니처가 존재하는지 확인할 수 있다. 특정 파일의 시그니처 이름을 통해 파일과 그 기능에 대한 추가 정보를 얻을 수 있다. 이런 정보는 이후 조사에 도움을 줄 뿐만 아니라 분석 시간도 줄여 준다.
3.1 VirusTotal 을 이용한 의심 바이너리 스캐닝
VirusTotal은 데이터 집합을 기반으로 구축한 VirusTotal Graph라는 유용한 기능을 제공한다. 이를 이용하면 등록한 파일과 도메인, IP 주소, URL과 같은 관련 지표 사이의 관계를 시각화할 수 있다. 또한 각 지표를 피봇하거나 둘러볼 수 있다. 이 기능은 악성코드 바이너리와 관련된 지표를 빠르게 파악하고자 하는 경우 매우 유용하다. VirusTotal Graph
다음 스크린샷은 본인 연구에서 분석하는 수많은 웹 플러그인 중 하나에 대해 탐지한 이름을 보여주며, 63개 벡신 엔진으로 바이너리를 스캔했음을 보여준다. 이 중 바이너리를 악성코드로 탐지한 건 0건이다.

3.2 VirusTotal 공개 API를 이용한 해시 값 질의
파이썬 바이러스토털 공개 API 사용을 보여주는 파이썬 스크립트이다. 이 스크립트는 입력값으로 해시값을 받아 바이러스 토털 DB에 질의한다. 스크립트를 실행해 바이너리의 MD5 해시를 전달하면 백신의 탐지 결과와 바이너리의 시그니처명을 보여준다.
import urllib
import urllib2
import json
import sys
hash_value = sys.argv[1]
vt_url = "https://www.virustotal.com/vtapi/v2/file/report"
api_key = "본인의 API키 업데이트"
parameters - {'api_key': api_key, 'resource': hash_value}
encoded_parameters = urllib.urlencode(parameters)
request = urllib2.Request(vt_url, enconded_parameters)
response = urllib2.urlopen(request)
json_response = json.loads(response.read())
if json_response['response_code']:
detections = json_response['positives']
total = json_response['total']
scan_results = json_response['scans']
print("Detections: %s/%s" % (detections, total)
print("VirusTotal Results: ")
for av_name, av_data in scan_results.items():
print("\t%s ==> %s") % (av_name, av_data['result'])
else:
print("No AV Detections For: %s" % hash_value)
다른 대안으로는 pestudio 또는 PPEE와 같은 PE 분석 도구가 있다. 바이너리를 로딩하면 바이너리의 해시 값을 바이러스토털 DB로 자동으로 질의한다.
$ md5sum 5340.exe
5340fcfb3d2fa263c280e9659d13ba93 5340.exe
$ python vt_hash_query.py 5340fcfb3d2fa263c280e9659d13ba93
Detections: 44/56
VirusTotal Results:
Bkav ==> None
MicroWorld-eScan ==> Trojan.Generic.11318045
nProtect ==> Trojan/W32.Agent.105472.SJ
CMC ==> None
CAT-QuickHeal ==> Trojan.Agen.r4
ALYac ==> Trojan.Generic.11318045
Malwarebytes ==> None
Zillya ==> None
SUPERAntiSpyware ==> None
TheHacker ==> None
K7GW ==> Trojan ( 001d37dc1 )
K7Antivirus ==> Trojan.Win32.Agent.cxbxiy
F-Prot ==> W32/Etumbot.K
Symantec ==> Trojan.Zbot
4. 문자열 추출
문자열 추출은 프로그램 기능과 의심 바이너리 관련 지표에 대한 단서를 제공한다. 예를 들어, 악성코드가 파일을 생성한다면 그 파일명이 바이너리 안에 문자열로 저장된다. 또는 공격자가 통제하는 도메인명을 악성코드가 호출한다면 해당 도메인명이 문자열로 저장된다. 바이너리에서 추출하는 문자열은 파일명, URL, 도메인명, IP주소, 공격 명령어, 레지스트리 키 등을 포함할 수 있다.
4.1 도구를 이용한 문자열 추출
의심 바이너리에서 문자열 추출을 위해 리눅스 시스템에서는 strings 유틸리티를 사용할 수 있다. strings 명령어는 기본적으로 최소 4문자 이상인 ASCII 문자열을 추출한다. -a 옵션을 이용하면 전체 파일에서 문자열을 추출할 수 있다. 악성코드 바이너리에서 추출한 다음의 ASCII 문자열은 IP 주소를 보여준다. 이는 악성코드가 실행됐을 때 해당 IP 주소로 접속을 시도할 수 있음을 의미한다.
$ strings -a log.exe
!This program cannot be run in DOS mode.
Rich
.text
`.rdata
@.data
L$"%
h4z@
128.91.34.188
%04d-%02d-%02d %02d:%02d:%02d %s
4.2 FLOSS를 이용한 난독화된 문자열 디코딩
대부분의 악성코드 제작자는 탐지를 회피하고자 간단한 문자열 ==난독화(obfuscation)== 기법을 사용한다. 이 경우 난독화된 문자열은 strings 유틸리티와 다른 추출 도구를 이용해 추출할 수 없다. FLOSS(FireEye Labs Obfuscated String Solver)는 악성코드에서 난독화된 문자열을 자동으로 추출하고 식별하고자 디자인된 도구다. FLOSS는 악성코드 제작자가 문자열 추출 도구를 피해 숨기고자 했던 문자열을 찾을 수 있도록 돕는다.
다음 예에서 FLOSS 단일 바이너리를 악성코드 샘플에 실행해 사람이 읽을 수 있는 문자열을 추출했을 뿐만 아니라 난독화된 문자열을 디코딩하고 strings 유틸리티와 다른 문자열 추출 도구에서 놓친 스택 문자열을 추출했다. 다음 결과는 실행 파일, 엑셀 파일, Run 레지스트리 키에 대한 참조를 보여 준다.
$ chmod +x floss
$ ./floss 5340.exe
FLOSS static ASCII strings
!This program cannot be run in DOS mode. Rich
.text
`.rdata
@.data
FLOSS decoded 15 strings
kb71271.log
R6002
- floating point not loaded
- \Microsoft
- winlogdate.exe
~ tasyd3.xls
FLOSS extracted 13 stack strings
BINARY
ka4a8213.log
afjlfjsskjfslkfjsdlkf
'Clt
~tasyd3.xls
"%s"="%s"
regedit /s %s
5. 파일 난독화 파악
악성코드 제작자는 난독화를 통해 악성코드 내부의 동작을 보안 연구자, 악성코드 분석가, 리버스 엔지니어로부터 보호한다. 난독화 기술은 바이너리를 탐지/분석하기 어렵게 하기 때문에 추출할 수 있는 문자열은 별로 되지 않으며 문자열 대부분은 모호하다. 악성코드 제작자는 백신과 같은 보안 제품의 탐지를 회피하고 분석을 방해하고자 패커(Packer)와 크립터(Cryptor) 같은 프로그램을 자주 사용한다.
패커 Packer
실행 파일을 입력으로 받아 실행 파일의 내용을 압축해 난독화하는 프로그램이다. 난독화한 콘텐츠는 새로운 실행 파일의 구조체에 저장된다. 디스크에 난독화된 콘텐츠를 담고 있는 새로운 실행 파일(패킹)이 결과물로 생긴다. 패킹한 프로그램을 실행하면 압축해제 루틴이 실행되고 메모리에 원본 바이너리를 추출한 후 실행한다.
크립터 Cryptor
실행 파일의 내용을 난독화하고자 압축 대신 암호화를 사용한다. 암호화한 내용은 새로운 실행 파일에 저장한다. 암호화한 프로그램을 실행할 때 복호화 루틴을 실행해 원본 바이너리를 메모리에 추출한 후 실행한다.