바이러스토탈 API 연동

네트워크 DPI 솔루션이나 EDR 등 엔드포인트 솔루션을 통해 의심스러운 바이너리 해시, IP 주소, 도메인을 수집한 경우, 바이러스토탈 API와 연계하여 악성 여부를 진단할 수 있습니다.

API 키 발급

바이러스토탈에 가입한 후 커뮤니티 프로필에서 아래와 같이 API 키를 확인할 수 있습니다.

모든 API는 JSON 형태로 응답을 반환하며, 아래의 속성을 포함하고 있습니다:

  • response_code: 1 (분석 결과 있음), 0 (분석 결과 없음), -2 (분석 진행중)
  • verbose_msg: 응답코드와 관련된 메시지

아래의 예시들은 임의로 진단결과가 존재하는 레코드를 만들어서 REST API를 호출하고 있으나, 예제 쿼리들을 스트림 쿼리로 설정하면 의심되는 정보를 실시간으로 바이러스토탈과 연동하여 조회할 수 있습니다. 다만, 커뮤니티 계정인 경우 바이러스토탈 서비스에서 분당 호출 횟수를 제한합니다.

예제 쿼리의 VIRUSTOTAL_API_KEY 부분은 발급받은 API 키로 교체하셔야 실행됩니다.

파일 해시 조회

json "{}" 
| eval md5 = "7657fcb7d772448a6d8504e4b20168b8" 
| eval url = concat("https://www.virustotal.com/vtapi/v2/file/report?apikey=VIRUSTOTAL_API_KEY&resource=", md5)
| wget 
| parsejson 
| parsemap field=line 
| fields scan_id, total, positives, md5, sha256

호출하는 URL의 resource 매개변수는 MD5, SHA1, SHA256 해시 중 하나를 사용할 수 있습니다. total은 전체 진단 수, positives는 악성으로 탐지된 수를 의미하므로, positives / total 비율이 높은 경우 악성코드로 진단할 수 있습니다.

IP 주소 조회

json "{}" 
| eval ip = "90.156.201.27"  
| eval url = concat("https://www.virustotal.com/vtapi/v2/ip-address/report?apikey=VIRUSTOTAL_API_KEY&ip=", ip)  
| wget 
| parsejson overlay=t 
| parsemap field=line 
| explode detected_urls 
| parsemap overlay=t field=detected_urls 
| fields ip, response_code, url, positives, total, scan_date

IP 분석 결과는 위의 스크린샷처럼 주어진 IP와 연관된 악성 URL 정보를 포함합니다.

도메인 조회

json "{}" 
| eval domain = "027.ru"  
| eval url = concat("https://www.virustotal.com/vtapi/v2/domain/report?apikey=VIRUSTOTAL_API_KEY&domain=", domain)  
| wget 
| parsejson overlay=t 
| parsemap field=line 
| explode detected_urls 
| parsemap overlay=t field=detected_urls
| fields domain, response_code, categories, url, positives, total, scan_date

도메인 분석 결과는 위의 스크린샷처럼 주어진 도메인과 연관된 악성 URL 정보를 포함합니다.

둘러보기

더보기

DNS 로그 분석을 통한 악성코드 추적

### 사건의 발단 평소처럼 구글에 접속하던 어느날, 사내 컴퓨터마다 아래와 같은 경고 창이 뜨면서 CAPTCHA 입력을 요구하는 일이 벌어졌습니다. ![Google CAPTCHA](/media/ko/2016-12-15-malware-and-dns/captcha.png) 모든 PC마다 안티바이러스를 추가로 설치해서 스캔해봤지만, 딱히 발견되는 악성코드도 없어서 난감한 상황이었습니다. 네트워크 관리자는 기존에 설치되어 있던 차세대 방화벽 로그를 분석하기 시작했습니다. ### 차세대 방화벽 로그 아래는 Cisco FirePower의 로그 예시입니다. 차세대 방화벽은 전통적인 방화벽과 다르게 응용 프로토콜 (L7) 수준에서 트래픽을 분석하고 메타데이터를 추출하는 기능을 제공합니다. 로그 예시에서 DNS 요청 도메인, URL 분류 및 평판 정보 등이 포함되어 있음을 확인할 수 있습니다. ``` Oct 18 14:56:54 FP60 SFIMS: Protocol: UDP, SrcIP: X.X.X.X, DstIP: 17.151.0.151, SrcPort: 45148, DstPort: 53, TCPFlags: 0x0, IngressInterface: eth1, IngressZone: Passive, DE: Primary Detection Engine (96f4547e-d715-11e5-b0f4-bdee139db4d8), Policy: FP_IDS_FILE_POLICY, ConnectType: End, AccessControlRuleName: IDS-FILE-RULE, AccessControlRuleAction: Allow, UserName: No Authentication Required, Client: DNS, ApplicationProtocol: DNS, InitiatorPackets: 1, ResponderPackets: 1, InitiatorBytes: 97, ResponderBytes: 146, NAPPolicy: Balanced Security and Connectivity, DNSQuery: gspe35-kr-ssl.ls.apple.com, DNSRecordType: a host address, DNSResponseType: No Error, DNS_TTL: 3600, Sinkhole: Unknown, URLCategory: Unknown, URLReputation: Risk unknown ``` 로그프레소에 많은 파서들이 내장되어 있지만, 쿼리만으로도 간단히 데이터를 아래와 같이 파싱할 수 있습니다. ``` table from=20161016 to=20161017 FP | eval line = substr(line, indexof(line, "Protocol:")) | parsekv pairdelim="," kvdelim=": " ``` ![FirePower Log Parsing](/media/ko/2016-12-15-malware-and-dns/parsekv.png) 일반적으로는 분석의 편의성을 위해 스트림 쿼리를 이용해서 실시간으로 정규화한 데이터를 컬럼지향 레이아웃의 테이블에 넣어놓고 고속으로 드릴다운 분석을 실행합니다. 구글이 감지할 정도의 이상 트래픽이라면, 방화벽 로그에서도 특별한 징후를 찾을 수 있을 것이라 예상할 수 있습니다. DNS 요청 추이를 시각화했을 때, 아래와 같은 양상을 보입니다. ``` table from=20161014 to=20161015 firepower | search SrcIP != ip("X.X.X.X") and SrcIP != ip("X.X.X.X") | search isnotnull(DNSQuery) | timechart span=10m count by SrcIP ``` ![DNS Chart](/media/ko/2016-12-15-malware-and-dns/dns-chart.png) 사내 DNS 서버는 역할 상 많은 DNS 요청을 할 수 밖에 없으므로 배제하고, 나머지 호스트들은 업무시간대에 맞춰서 DNS 요청이 증가하는 현상을 볼 수 있습니다. 그런데 새벽시간 대에도 아주 일정하게, 다수의 DNS 요청을 전송하는 내부 PC가 보입니다. 좀 더 확실하게 보기 위해서, 해당 호스트의 DNS 요청에 대한 통계를 내봤습니다. ``` table from=20161014 to=20161015 firepower | search SrcIP == ip("Y.Y.Y.Y") | search isnotnull(DNSQuery) | stats count by DNSQuery, DNSResponseType | sort -count ``` ![Domain Stats](/media/ko/2016-12-15-malware-and-dns/domain-stats.png) 최상단에 다수의 DNS 응답 실패를 유발한 도메인이 보입니다. 이 도메인으로 위협 정보를 검색했을 때 아래와 같은 내용을 확인할 수 있었습니다. * Remove PUP.Optional.NextLive.A (Virus Removal Guide) * Microsoft Forum: Remove newnext.me virus ### 애드웨어 확인 실제 감염된 것으로 의심되는 윈도우 PC를 조사했을 때, 아래와 같이 nengine.dll 파일과 레지스트리에 등록된 흔적을 확인할 수 있었습니다. #### DLL 파일 ![Nengine DLL](/media/ko/2016-12-15-malware-and-dns/nengine-dll.png) #### 레지스트리 ![Nextlive](/media/ko/2016-12-15-malware-and-dns/nextlive-registry.png) ### 안티바이러스의 미탐지 네트워크에 남겨진 다수의 DNS 흔적, 실제 PC의 악성 파일 및 레지스트리를 확인했음에도 불구하고, 여전히 대부분의 안티바이러스는 이 애드웨어를 진단하지 않았습니다. 악성코드를 이용해서 돈을 버는 이런 류의 회사들은 안티바이러스에 악성코드로 등록되면 소송을 걸기도 하는데, 이 때문에 안티바이러스 벤더는 눈에 띄일 정도의 피해가 없으면 애드웨어를 탐지하지 않도록 처리하기도 합니다. 한편, 차세대 방화벽을 가지고 있지 않더라도 DNS 로그를 분석함으로써 우리는 네트워크에서 어떤 일이 일어나고 있는지 상당 부분 가시성을 확보할 수 있으며, 이러한 시계열 통계 데이터를 기존 추이와 비교하여 자동화된 이상징후 탐지를 시도할 수도 있습니다. 최근의 악성코드들은 DGA (Domain Generation Algorithm) 기법을 이용하여, IP 기반의 차단을 회피하고 C2 서버와 통신하는 경우가 흔합니다. 일반적으로 악성코드의 통신 자체는 암호화되지만 이와 같이 외부의 제어서버와 통신하기 위한 DNS 요청 자체는 숨기기 어려우며, 평상시 접속하는 도메인에 대한 프로파일링을 통해 좀 더 견고한 탐지 체계를 갖출 수 있습니다.

2016-12-15

DHCP를 통한 자산 프로파일링

네트워크 보안 관리는 내부에 어떤 호스트들이 존재하는지 파악하는데서 출발합니다. 큰 범위에서는 방화벽을 이용하여 트래픽의 흐름을 제어하지만, 특정 세션이 정말 허용된 트래픽인지, 침입방지시스템에서 경보한 익스플로잇이 해당 호스트에 유효한 공격인지 식별하기 위해서는 자산에 대한 상세한 메타데이터가 필요합니다. 과거에는 자산 정보를 수작업으로 관리할 수 있었지만, 개인이 사용하는 모바일 장치가 증가하고 인터넷에 접근하는 기기의 종류가 늘어나면서 자동화된 자산 정보 구축이 중요해졌습니다. 최근의 네트워크 접근 제어 (NAC; Network Access Control) 솔루션들은 자산 정보의 자동 수집과 네트워크 접근 권한 제어를 수행하는데, 로그프레소는 별도의 NAC이 없는 경우에도 자산 프로파일링을 자동화할 수 있는 방법을 제공합니다. 그 중 하나는 DHCP 핑거프린팅입니다. ### DHCP 프로토콜 아래의 스크린샷은 와이어샤크로 살펴본 DHCP 패킷 샘플입니다. 원본 PCAP 파일은 Chris Sanders 웹사이트에서 다운로드할 수 있습니다. ![](/media/ko/2017-01-14-dhcp-fingerprinting/dhcp-wireshark.png) 스크린샷에서 확인할 수 있듯이 각 DHCP 요청 패킷은 MAC, IP 주소 정보 뿐 아니라, 호스트 이름 (Client Identifier 옵션), 제조사 (Vendor class identifier) 정보를 포함하고 있습니다. 더 중요한 부분은 매개변수 요청 목록 (Parameter Request List) 옵션이 운영체제나 기기에 따라 조금씩 다르기 때문에, 일종의 지문처럼 활용할 수 있다는 사실입니다. ### DHCP 핑거프린팅 로그프레소는 decodedhcp 커맨드를 이용해서 DHCP 패킷을 파싱할 수 있도록 지원합니다. ```query pcapfile dhcp_inlease_renewal.pcap | decodedhcp ``` ![](/media/ko/2017-01-14-dhcp-fingerprinting/decodedhcp.png) 아래의 쿼리는 호스트 이름 추출 예시입니다. foreach 함수는 options 필드를 순회하면서 name이 HostName인 옵션을 찾아 BLOB 값을 decode 하여 호스트 이름 문자열로 복원합니다. ```query pcapfile dhcp_inlease_renewal.pcap | decodedhcp | eval host_name = strjoin("", foreach(if(valueof(_1, "name") == "HostName", decode(valueof(_1, "value")), ""), options)) | eval host_name = if(len(host_name) > 0, host_name, null) | fields client_ip, client_mac, host_name ``` ![](/media/ko/2017-01-14-dhcp-fingerprinting/dhcp-options.png) 아래의 쿼리는 DHCP 핑거프린트 룩업 DB를 이용하여 호스트의 운영체제를 식별하는 예시입니다. ```query pcapfile dhcp_inlease_renewal.pcap | decodedhcp | eval host_name = strjoin("", foreach(if(valueof(_1, "name") == "HostName", decode(valueof(_1, "value")), ""), options)) | eval host_name = if(len(host_name) > 0, host_name, null) | lookup dhcp_fingerprint fingerprint output category as os_category, vendor as os_vendor, family as os_family, description as os_name | fields host_name, client_ip, client_mac, os_category, os_vendor, os_family, os_name, fingerprint ``` ![](/media/ko/2017-01-14-dhcp-fingerprinting/dhcp-fingerprint-lookup.png) 로그프레소에 내장된 DHCP 핑거프린트 룩업은 200개 이상의 핑거프린트를 포함하며 아래의 메타데이터를 제공합니다: * category: 20종 이상의 장치 분류 (예: Desktop oriented operating system) * vendor: 60종 이상의 제조사 (예: Microsoft Corporation) * family: 90종 이상의 장치 유형 (예: Microsoft Windows NT) * description: 운영체제/기기 이름 (예: Windows 7) 위의 예시는 PCAP 파일을 대상으로 한 쿼리이지만, 로그프레소는 풀 패킷 캡처 엔진을 내장하고 있으므로 실시간으로 DHCP 트래픽을 수집하여 자산 데이터베이스 구축을 자동화할 수 있습니다.

2017-01-14

의사결정나무를 이용한 이상탐지

기계학습 분야에는 이상치(outlier)를 탐지하는 다양한 알고리즘이 제안되어 있지만, 알고리즘마다 특성이 있기 때문에 이를 잘 알아두어야 문제 풀이에 적합한 기계학습 알고리즘을 선택할 수 있습니다. 이번 절에서는 데이터 기반 의사결정에 광범위하게 사용되는 의사결정나무(Decision tree)를 이용하여 이상탐지를 수행하는 방법을 설명합니다. 이상치는 정상치에 비해 매우 다른 특징을 가진 데이터를 의미합니다. 일반적으로는 이상치를 찾기 위해 정상치를 학습하고, 정상치와 달라보이는 이상치를 추출합니다. 가장 쉽고 간단하게 생각할 수 있는 방법은 통계적으로 평균과 표준편차를 구해서, 이와 크게 벗어나는 값을 이상치로 취급하는 방법입니다. 여기서 더 나아가 다차원 데이터를 취급할 때는 군집 기반의 방법론을 주로 사용합니다. 아래의 도표는 LOF (Local Outlier Factor) 알고리즘이 군집에서 멀리 떨어진 값을 이상치로 계산한 예시입니다. ![](/media/ko/2017-08-22-anomaly-detection/lof.png) 이러한 기존 방법론의 가장 큰 문제는 1) 정상치를 모두 고려해야 하므로 계산 부하가 크다는 점, 2) 매번 정상치를 프로파일링해서 이상치를 계산하므로 모델을 생성하고 재활용하기 어렵다는 점입니다. Isolation Forest 기계학습 알고리즘은 기존 방법론과 다르게, 이상치 기준을 모델로 생성하는 방법론을 제시합니다. ## 공간분할 기반 이상탐지 아래의 그림은 2차원 데이터를 대상으로 Isolation Forest의 동작을 시각적으로 보여줍니다. ![](/media/ko/2017-08-22-anomaly-detection/isolation-forest.png) Isolation Forest 알고리즘은 랜덤하게 차원을 선택해서 임의의 기준으로 공간을 분할합니다. 군집 내부에 있는 정상치 Xi의 경우 공간 내에 한 점만 남기고 완전히 고립시키려면 많은 횟수의 공간 분할을 수행해야 하지만, 군집에서 멀리 떨어진 이상치 Xo는 적은 횟수의 공간 분할만으로 고립시킬 수 있습니다. 공간분할은 차원과 기준 값으로 표현할 수 있으므로, 여러 번의 공간분할은 의사결정나무 (Decision Tree) 형태로 표현할 수 있습니다. 정상치일수록 완전히 고립시킬 수 있을 때까지 의사결정나무를 깊숙하게 타고 내려가야 합니다. 반대로 이상치의 경우, 의사결정나무의 상단부만 타더라도 고립될 가능성이 높습니다. 이런 특성을 이용하면 의사결정나무를 몇 회 타고 내려가야 고립되는가를 기준으로 정상치와 이상치를 분리할 수 있습니다. ![](/media/ko/2017-08-22-anomaly-detection/isolation-forest-score-map.png) 이런 의사결정나무를 여러 개 모아서 앙상블 모델을 만들면 왼쪽 그래프처럼 안정적인 이상지수(score)를 산출할 수 있습니다. 논문에서는 약 50개에서 100개 정도의 의사결정나무를 이용하면 이상지수가 안정화된다는 점을 언급하고 있습니다. 오른쪽 그래프는 등고선 형태로 군집의 경계에 해당하는 점들은 0.5의 이상지수를 가진다는 사실을 보여주고 있습니다. 이상지수는 0~1 범위로 정규화되므로, 일반적으로 0.5보다 크고 1에 가까울수록 이상치로 정의할 수 있습니다. ## 이상탐지 수행 성능 Isolation Forest는 군집기반 이상탐지 알고리즘에 비해 월등한 실행 성능을 보입니다. 군집기반 이상탐지 알고리즘의 경우, 자기 자신을 제외한 나머지 모든 인스턴스에 대한 유클리디안 거리를 계산해야 하므로 O(N2)의 수행시간이 필요합니다. 반면, Isolation Forest는 일부 데이터를 샘플링하여 의사결정나무 모델을 생성하고 이를 이용하여 이상탐지를 수행하므로 O(logN)의 수행시간이면 충분합니다. 또 하나는 정확성에 대한 부분인데, 이상탐지 분야에서 해결하기 어려운 문제는 Swamping과 Masking이라 불리는 현상입니다. Swamping은 정상치가 이상치에 가까운 경우 이상치로 잘못 분류하게 되는 현상이고, Masking은 이상치가 군집화되어 있으면 정상치로 잘못 분류하게 되는 현상입니다. ![](/media/ko/2017-08-22-anomaly-detection/isolation-forest-sample.png) Isolation Forest는 전수 데이터를 이용하지 않고 일부 데이터만 샘플링해서 모델을 생성하기 때문에, 상대적으로 이런 오류에 강건한 특성을 가지게 됩니다. 위의 도표는 이상치 군집과 정상치 군집이 가까이 있을 때, 샘플링이 어떻게 이러한 문제를 극복하는지 시각적으로 보여주고 있습니다. ## 로그프레소의 활용 로그프레소에서는 기계학습을 쿼리로 수행할 수 있을 뿐 아니라, 스트림 쿼리에 이미 생성된 기계학습 모델을 배포(Deploy)하여 밀리초 이내의 실시간 이상탐지를 수행할 수 있도록 지원합니다. 예를 들어, 이상금융거래시스템(FDS)은 고객정보, 거래정보, 단말정보 등 다차원 데이터를 이용하여 이상탐지 모델을 생성하고 이를 기반으로 0.1초 이내에 실시간 탐지를 수행합니다. 아래는 실제 환경과 유사한 거래 데이터를 가상으로 생성하여 만든 모델링 데모입니다. 이 중에서 거래시각, 고객연령, 연속이체횟수 특성의 분포를 살펴보면 다음과 같습니다. ![](/media/ko/2017-08-22-anomaly-detection/fds-histogram.png) 거래시각은 0-86400초 범위의 값, 연령은 0-100 범위의 값, 연속이체횟수는 0-16 범위의 값을 가지고 있습니다. anomalies 쿼리를 사용하면 서브쿼리 결과를 이용하여 Isolation Forest 모델을 즉시 생성하고 이를 이용하여 스코어링을 실행할 수 있습니다. ```query table transaction | anomalies _time, age, cnt [ table transaction ] | eval category = if(_score >= 0.7, "outlier", "normal") ``` 3차원으로 시각화하면 아래와 같이 색상으로 분리된 정상 거래와 이상 거래를 확인할 수 있습니다. ![](/media/ko/2017-08-22-anomaly-detection/fds-3d-histogram.png) 위의 예시는 설명을 위해 극단적으로 단순화한 모델이며, 실제로는 수집 데이터 원본 뿐 아니라 CEP (Complex Event Processing) 기술을 통해 생성된 다양한 특성 값의 분포와 영향력을 비교하고 가공하는 과정을 거치게 됩니다. 기존의 룰/시나리오 기반 탐지 모델은 각각의 차원에 대해 임계치를 정의하고 조합했지만, 기계학습을 이용한 이상탐지는 다차원으로 데이터를 분석하고 경계면을 자동 생성함으로써 더 정교한 탐지를 수행할 수 있습니다. ## 레퍼런스 * Liu, Fei Tony, Ting, Kai Ming and Zhou, Zhi-Hua. "Isolation forest." Data Mining, 2008. ICDM'08. Eighth IEEE International Conference on Data Mining. * Liu, Fei Tony, Ting, Kai Ming and Zhou, Zhi-Hua. "Isolation-based anomaly detection." ACM Transactions on Knowledge Discovery from Data (TKDD) 6.1 (2012)

2017-08-22