Sysmon을 이용한 엔드포인트 포렌식

우리는 많은 비용과 노력을 들여 보안체계를 구축하지만, 임직원의 피싱 메일 첨부파일 실행과 같은 작은 부주의로도 공격자가 쉽게 내부로 침투할 수 있습니다.

방화벽이나 침입방지시스템 로그는 트래픽의 흐름과 알려진 네트워크 위협들을 가시적으로 보여주지만, 단지 방화벽 로그에 남아있는 IP와 포트만을 근거로 단말에서 어떤 프로세스가 어떻게 실행되어서 어떤 경로로 전파된 것인지 사후 추적하는 것은 불가능에 가깝습니다.

최근 몇 년 사이에 안티바이러스를 보완하는 EDR (Endpoint Detection & Response)이 빠르게 도입되고 있습니다. EDR은 단말에서 발생하는 모든 행위들을 중앙 서버에 기록하고 분석함으로써, 악성코드의 감염과 확산 경로를 효율적으로 탐지하고 추적할 수 있도록 지원합니다.

예전에는 수천 대의 단말마다 발생하는 수많은 프로세스의 실행, 네트워크 연결 기록들을 DB에서 관리하는게 불가능하다고 여겨졌지만, 발전된 빅데이터 기술이 이 모든 것을 가능하게 한 것입니다.

EDR 솔루션을 도입할 수 있는 여건이라면 좋겠지만, 그렇지 않은 경우에도 마이크로소프트에서 배포하는 Sysmon을 이용해서 엔드포인트 보안 체계를 강화할 수 있습니다.

Sysmon은 아래와 같은 시스템 행위들을 윈도우 이벤트 로그로 기록합니다.

  • 프로세스의 생성 및 종료
  • 드라이버 로드
  • 실행 이미지 로드
  • 파일 생성 시각 변조
  • 네트워크 연결
  • CreateRemoteThread API 사용
  • RawAccessRead API 사용
  • Sysmon 서비스 상태 변경

아래에서는 로그프레소 센트리를 통해 Sysmon 이벤트를 수집한 예제를 하나씩 살펴보고, 이를 어떻게 외부의 위협 인텔리전스와 연동하여 탐지 및 분석할 수 있는지 알아봅니다.

프로세스 실행 분석

table sysmon | fields _time, event_id, level, line

Process Create:
UtcTime: 2017-01-19 14:26:38.692
ProcessGuid: {9D15E6DA-CC9E-5880-0000-0010ECBA5E33}
ProcessId: 12644
Image: C:\Program Files\Git\mingw64\bin\git.exe
CommandLine: git.exe status -z -u
CurrentDirectory: 작업디렉터리
User: 사용자이름
LogonGuid: {9D15E6DA-****-****-****-************}
LogonId: 0xA2****
TerminalSessionId: 2
IntegrityLevel: Medium
Hashes: SHA256=B388344FEB34B1CB4E7566D846C85587B843181999C05BA00C82FE208CA4909B
ParentProcessGuid: {9D15E6DA-CC9E-5880-0000-001080B85E33}
ParentProcessId: 19180
ParentImage: C:\Program Files\Git\cmd\git.exe
ParentCommandLine: "C:\Program Files\Git\cmd\git.exe" status -z -u

위의 스크린샷은 프로세스 생성 및 종료 시 남겨진 이벤트 로그의 예시입니다. 아래와 같이 쿼리를 사용해서 간단히 이벤트 메시지를 파싱할 수 있습니다.

table sysmon 
| search line == "*Process Create*" 
| eval line = substr(line, indexof(line, ":") + 3), line = replace(line, "\n", "`") 
| parsekv overlay=t pairdelim="`" kvdelim=": "
| eval Hashes = substr(Hashes, indexof(Hashes, "SHA256=") + 7)  

많은 프로세스 실행 기록이 남아있지만, SHA256 해시를 기준으로 통계내면 400개의 실행 이미지로 요약됩니다.

table sysmon 
| search line == "*Process Create*" 
| eval line = substr(line, indexof(line, ":") + 3), line = replace(line, "\n", "`") 
| parsekv overlay=t pairdelim="`" kvdelim=": "
| eval Hashes = substr(Hashes, indexof(Hashes, "SHA256=") + 7)  
| stats count by Image, Hashes | sort -count

초기 화이트리스팅 작업을 통해 정상 이미지는 배제하고, 바이러스토탈 등 외부 인텔리전스 서비스를 연동하면 효율적으로 악성코드를 진단할 수 있습니다. 만약 특정 바이너리가 악성코드로 진단된 경우, 원본 이벤트 로그에 아래와 같이 부모 프로세스에 대한 정보가 남아있으므로 충분히 감염 경로를 역추적 할 수 있습니다.

ParentProcessGuid: {9D15E6DA-CC9E-5880-0000-001080B85E33}
ParentProcessId: 19180
ParentImage: C:\Program Files\Git\cmd\git.exe
ParentCommandLine: "C:\Program Files\Git\cmd\git.exe" status -z -u

같은 악성코드 해시가 여러 대의 시스템에서 발견된다면, 이벤트 로그를 시간순으로 정렬하여 어느 호스트로부터 악성코드가 전파되기 시작했는지 분석할 수 있습니다.

네트워크 연결 분석

네트워크 연결 이벤트는 프로세스 ID와 이미지 경로를 포함하여 정확하게 어느 프로세스가 어떤 호스트와 통신했는지 보여줍니다.

Network connection detected:
UtcTime: 2017-01-19 14:54:26.027
ProcessGuid: {9D15E6DA-483F-5876-0000-00105E39B000}
ProcessId: 10336
Image: C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
User: 사용자명
Protocol: tcp
Initiated: true
SourceIsIpv6: false
SourceIp: 172.20.XXX.XXX
SourceHostname: 출발지호스트명
SourcePort: 53563
SourcePortName: 
DestinationIsIpv6: false
DestinationIp: XXX.XXX.XXX.XXX
DestinationHostname: 
DestinationPort: 80
DestinationPortName: http

마찬가지로 아래와 같이 쿼리를 사용해서 간단히 이벤트 메시지를 파싱할 수 있습니다.

table sysmon | search line == "*Network connection detected*" 
| eval line = substr(line, indexof(line, ":") + 3), line = replace(line, "\n", "`") 
| parsekv overlay=t pairdelim="`" kvdelim=": " 
| fields _time, ProcessId, Image, Protocol, SourceIp, SourcePort, SourcePortName, DestinationIp, DestinationPort

이번에는 맬웨어도메인리스트와 연계하여 분석해보도록 하겠습니다. 데모를 위해 맬웨어도메인리스트에 등록된 악성 IP 중 하나에 일부러 접속해서 이벤트를 발생시켰습니다.

table sysmon 
| search line == "*Network connection detected*" 
| eval line = substr(line, indexof(line, ":") + 3), line = replace(line, "\n", "`") 
| parsekv overlay=t pairdelim="`" kvdelim=": " 
| join DestinationIp [ 
    wget url="http://www.malwaredomainlist.com/hostslist/ip.txt"
    | eval ip = split(line, "\r\n")
    | fields ip
    | explode ip
    | rename ip as DestinationIp 
]
| fields _time, ProcessId, Image, Protocol, SourceIp, SourcePort, DestinationIp, DestinationPort

위의 쿼리는 wget 커맨드를 사용해서 맬웨어도메인리스트의 IP 목록을 다운로드한 후 개행문자로 분리하여 즉석에서 IP 블랙리스트 데이터셋을 생성하고 이를 로컬의 윈도우 이벤트와 조인합니다. 위의 쿼리를 로그프레소의 스트림 쿼리로 설정하면, 외부 위협 인텔리전스를 이용하여 밀리초 단위의 실시간으로 탐지 및 경보할 수 있습니다.

위에 설명한 항목들 외에도 Sysmon은 유용한 이벤트 로그들을 생성하므로, 엔드포인트에 일괄 배포하여 이벤트 로그를 실시간으로 수집하고 탐지하면 엔터프라이즈 보안 및 분석 역량을 한단계 끌어올릴 수 있습니다.

둘러보기

더보기

NTFS 포렌식

NTFS는 윈도우즈 운영체제에서 지금까지 사용하고 있는 파일시스템입니다. 파일시스템은 물리적인 디스크 공간을 논리적인 디렉터리 계층과 파일 단위로 구조화하여 사용할 수 있도록 만들어줍니다. 스마트폰이 대중화된 이후 포렌식의 분석 대상이 개인정보를 집적하고 있는 모바일 기기로 많이 이동하고 있지만 여전히 윈도우즈 운영체제는 업무에서 핵심적인 생산성 도구입니다. 악성코드에 감염되거나 정보가 유출되었을 때 호스트에서 어떤 일이 발생했는지 알아내려면 NTFS 파일시스템에 대한 이해가 필수적입니다. ## MFT: 마스터 파일 테이블 ![](/media/ko/2020-09-12-ntfs-forensic/mft-structure.png) 마스터 파일 테이블은 NTFS 파일시스템에 존재하는 모든 디렉터리와 파일에 대한 메타데이터를 유지합니다. 마스터 파일 테이블은 1024바이트 고정 길이 레코드로 구성되어 있으며, 파일 삭제 여부, 파일 크기, 디스크 할당 크기 등을 48바이트의 MFT 헤더에 담고 있습니다. 파일 이름, 접근 권한, 파일 생성/수정/접근 일시 등의 정보는 MFT 헤더 뒤에 이어지는 여러 가지의 속성 (Attribute) 에 포함됩니다. 분석에 가장 흔히 사용되는 속성은 $STANDARD_INFORMATION 과 $FILE_NAME 속성이며, 아래의 필드를 포함하고 있습니다. * 파일 이름 * 디스크 할당 크기 * 실제 크기 * 파일 생성 일시 * 파일 수정 일시 * MFT 레코드 변경 일시 * 파일 액세스 일시 * 파일 권한 * 파일 속성 (숨김, 압축 등) 파일을 삭제하더라도 마스터 파일 테이블에서 즉시 삭제되지는 않으므로, 악성코드나 중요한 증적 파일이 삭제되더라도 MFT에서 삭제 흔적을 확인할 수 있습니다. 로그프레소 포렌식의 ntfs-mft 커맨드는 아래와 같은 필드 출력을 제공합니다. * no: MFT 인덱스 번호 * file_path: 파일 경로 * file_name: 파일 이름 * file_size: 파일 크기 * alloc_size: 디스크 할당 크기 * in_use: 삭제 여부 * is_dir: 디렉터리 여부 * link_count: 하드링크 수 * created_at: 파일 생성일시 ($FILENAME 속성) * modified_at: 파일 변경일시 ($FILENAME 속성) * access_at: 파일 접근일시 ($FILENAME 속성) * mft_modified_at: MFT 레코드 변경일시 ($FILENAME 속성) * std_created_at: 파일 생성일시 ($STANDARD_INFORMATION 속성) * std_modified_at: 파일 수정일시 ($STANDARD_INFORMATION 속성) * std_mft_modified_at: MFT 레코드 변경일시 ($STANDARD_INFORMATION 속성) * std_access_at: 파일 접근일시 ($STANDARD_INFORMATION 속성) * is_readonly: 읽기전용 여부 * is_hidden: 숨김 여부 * is_system: 시스템 파일 여부 * is_archive: 보관 가능 여부 * is_device: 장치 여부 * is_normal: 일반 여부 * is_temp: 임시 파일 여부 * is_sparse: Sparse 여부 * is_reparse: Reparse 여부 * is_compressed: 압축 여부 * is_offline: 오프라인 여부 * is_indexed: 인덱스 여부 * is_encrypted: 암호화 여부 * lsn: $LogFile 시퀀스 번호 * seq: MFT 레코드 시퀀스 (레코드 재할당 시 증가) * file_ref: 파일 참조 번호 * parent_file_ref: 디렉터리 파일 참조 번호 * parent_no: 디렉터리 MFT 인덱스 번호 ## USNJRNL: 저널링 로그 MFT에서 파일 삭제를 확인할 수는 있지만 사건을 조사할 때 또 하나 중요한 부분은 삭제 시점입니다. NTFS 파일시스템은 저널링을 지원하기 때문에, 파일 변경 이력을 $Extend 폴더의 $UsnJrnl 파일에 기록합니다. ![](/media/ko/2020-09-12-ntfs-forensic/usnjrnl-structure.png) 따라서 USNJRNL 파일을 분석하면 시스템에서 언제, 어떤 파일을 대상으로 어떤 작업을 수행했는지 파악할 수 있습니다. ntfs-usnjrnl 커맨드는 아래와 같은 필드 출력을 제공합니다. * _time: 파일 이벤트 시각 * file_name: 파일 이름 * file_no: MFT 인덱스 번호 * file_ref: 파일 참조 번호 * parent_file_no: 디렉터리 MFT 인덱스 번호 * parent_file_ref: 디렉터리 참조 번호 * reason: 파일 작업 목록 * usn: 레코드 오프셋 (Update Sequence Number) 저널링 로그는 MFT를 번호로 참조하기 때문에, 아래와 같이 조인하여 완전한 파일 경로를 확보할 수 있습니다. ```query ntfs-usnjrnl USNJRNL | join file_no [ ntfs-mft MFT | rename no as file_no ] ``` ![](/media/ko/2020-09-12-ntfs-forensic/ntfs-usnjrnl-join.png) 이러한 파일 변경 이력은 간단히 통계 처리하여 아래와 같이 타임라인을 시각화 할 수도 있습니다. ```query ntfs-usnjrnl USNJRNL | explode reason | timechart span=1h count by reason ``` ![](/media/ko/2020-09-12-ntfs-forensic/ntfs-usnjrnl-timechart.png) ## 코드게이트 포렌식 문제 연습 로그프레소 포렌식 솔루션은 쿼리를 기반으로 다양한 포렌식 아티팩트를 연관 분석하는 강력한 기능을 지원합니다. 아래에서는 이전 코드게이트 2012 컨퍼런스에서 NTFS와 관련하여 출제된 문제를 어떻게 분석하는지 설명합니다. > In Energy corporate X which is located in Seoul, APT(Advanced Persistent Threat) was occurred. For 6 months, Attacker A has stolen critical information with an elaborate attack. > Attacker A exerted great effort to remove his all traces such as malicious file, prefetch, registry and event logs for the period of attacking, so it was hard for Energy Corporate X to find an attacking path. > However IU who is Forensic expert can find the traces of the malicious files Attacker A used by analyzing MFT (Master File Table). > What time malicious file was created? The time is based on Korea Standard Time (UTC +09:00) * Codegate 2012 Forensic 400 문제 파일 400점 문제이지만 풀이 방법을 알면 간단하게 접근할 수 있습니다. 문제 지문에서는 MFT를 분석 대상으로 제시하고 있고, 공격자가 프리페치를 삭제하려고 시도하였다고 언급하여 실행 파일을 암시하고 있습니다. 문제의 목표는 악성코드 생성일시를 찾는 것입니다. ```query ntfs-mft E:\codegate2012\$MFT | search file_name == "*.exe" ``` ![](/media/ko/2020-09-12-ntfs-forensic/codegate-query.png) 간단한 확장자 검색으로 휴지통에 있는 r32.exe 파일이 2012-02-23 02:39:18 KST에 생성되었고 파일 크기가 82944 바이트라는 사실을 확인할 수 있습니다.

2020-09-12

CEF 로그 포맷

CEF는 공통 이벤트 포맷 (Common Event Format)의 약어로, 아크사이트 등 ESM이나 SIEM 시스템과 연동할 목적으로 흔히 사용되는 규격입니다. 이 문서에서는 CEF 포맷의 세부사항을 다룹니다. ## CEF 헤더 규격 CEF 포맷은 아래와 같이 구성됩니다. ``` Jan 18 11:07:53 호스트 CEF:버전|제조사|제품모델|제품버전|이벤트 클래스 ID|이벤트 이름|위험도|[확장] ``` * 버전: CEF 포맷 자체의 버전을 의미합니다. 현재 유효한 값은 0 입니다. * 제조사: 로그를 전송하는 장치의 제조사를 의미합니다. * 제품모델: 로그를 전송하는 장치의 제품모델을 의미합니다. 제조사와 제품모델의 쌍으로 유일하게 해당 제품을 식별할 수 있어야 합니다. * 제품버전: 로그를 전송하는 장치의 버전을 의미합니다. * 이벤트 클래스 ID: 이벤트 유형별로 유일한 식별자입니다. 숫자일 수도 있고, 문자열일 수도 있습니다. 일반적으로 IPS의 시그니처 ID가 기입됩니다. * 이벤트 이름: 사람이 읽을 수 있는 형태의 이벤트 설명이 기록됩니다. 이 항목에는 IP나 포트처럼 특정한 정보는 포함하지 않고 이벤트 클래스 ID와 연결된 설명을 기록합니다. * 위험도: 이벤트 중요도를 문자열이나 숫자로 표현합니다. 문자열인 경우 유효한 값은 Unknown, Low, Medium, High, Veri-High 입니다. 숫자인 경우 유효한 값은 0~3 (Low), 4~6 (Medium), 7~8 (High), 9~10 (Very-High) 입니다. ## CEF 확장 CEF 헤더 뒷부분은 키=값 쌍으로 기술됩니다. 각각의 키=값 쌍은 공백으로 구분되며, 순서에는 제약이 없습니다. CEF 확장 필드는 값의 타입에 따라 커스텀 필드의 이름이 결정됩니다. 예를 들면 다음과 같습니다. * cn1 (custom number 1): 정수 필드, cn3까지 지정 가능 * cfp1 (custom floating point 1): 실수 필드, cfp4까지 지정 가능 * cs1 (custom string 1): 문자열 필드, cs6까지 지정 가능 * c6a1 (custom ipv6 address 1): IPv6 주소 필드, c6a4까지 지정 가능 각각의 커스텀 필드 값에 해당되는 필드 이름은 Label 접미사가 붙은 필드로 지정됩니다. 예를 들어, cn1 필드 값에 대한 필드 이름은 cn1Label 필드에 기록됩니다. 주로 사용되는 표준화된 확장 필드는 다음과 같습니다: | CEF 키 | 전체 이름 | 타입 | 최대길이 | 설명 | | ---------- | --------------------- | ---------- | ------------------------------- | ---------------------------------------------------------------------------------------------------- | | externalId | externalId | 문자열 | 40 | 원본 데이터 식별자 (Primary Key 등) | | rt | deviceReceiptTime | 타임스탬프 | | 이벤트를 수신한 시각, MMM dd yyyy HH:mm:ss 포맷이거나 1970년 1월 1일에서 시작하는 UNIX 타임스탬프 값 | | dvc | deviceAddress | IPv4 주소 | | 이벤트와 관련된 장치의 IPv4 주소 | | dvchost | deviceHostName | 문자열 | 100 | 이벤트와 관련된 장치의 호스트 이름 | | src | sourceAddress | IPv4 주소 | | 출발지 IPv4 주소 | | spt | sourcePort | 정수 | 0~65535 사이의 출발지 포트 번호 | | shost | sourceHostName | 문자열 | 1023 | 출발지 호스트 이름 | | smac | sourceMacAddress | MAC | | 콜론으로 구분된 출발지 MAC 주소 | | dst | destinationAddress | IPv4 주소 | | 목적지 IPv4 주소 | | dpt | destinationPort | 정수 | | 0~65535 사이의 목적지 포트 번호 | | dhost | destinationHostName | 문자열 | 1023 | 목적지 호스트 이름 | | dmac | destinationMacAddress | MAC | | 콜론으로 구분된 목적지 MAC 주소 | | msg | message | 문자열 | 1023 | 멀티라인을 포함할 수 있는 상세 메시지 | ## 메세지 인코딩 규칙 메세지는 아래의 규칙으로 인코딩합니다. * 문자집합: 전체 메세지는 UTF-8로 인코딩합니다. * 파이프: 파이프(|) 문자는 헤더의 각 구성요소를 구분하는데 사용하므로, 값에 파이프 자체를 표현해야 하는 경우 백슬래시를 앞에 붙여서 이스케이프해야 합니다. * 백슬래시: 백슬래시(\) 문자는 이스케이프로 사용하므로, 값에 백슬래시 자체를 표현해야 하는 경우 백슬래시(\)를 앞에 하나 더 붙여야 합니다. * 등호: 등호(=) 문자는 CEF 메세지 확장 부분에서 키와 값을 구분하는 용도로 사용하므로, 값에 등호 자체를 표현해야 하는 경우 백슬래시(\)를 앞에 하나 더 붙여야 합니다. 단, 헤더 부분에서는 등호를 이스케이프하지 않습니다. * 개행: 멀티라인으로 구성된 필드는 개행을 \r이나 \n으로 표현합니다. 단, 개행은 확장의 값 표현에만 허용됩니다. ## CEF 로그 예제 CEF를 사용하는 파이어아이 NX 시리즈의 로그 예시는 아래와 같습니다. ``` fenotify-20252856.warning: CEF:0|FireEye|CMS|7.8.1.468932|DM|domain-match|1|rt=Oct 19 2016 01:04:40 UTC src=172.20.1.23 cn3Label=cncPort cn3=53 cn2Label=sid cn2=80448589 shost=dns.example.com proto=udp spt=23619 cs5Label=cncHost cs5=acme.com dvchost=EXAMPLE-NX2 dvc=192.168.10.11 smac=e4:c7:22:2a:c7:d2 cn1Label=vlan cn1=0 externalId=10352856 cs4Label=link cs4=https://example.com/event_stream/events_for_bot?ev_id\=10352856 act=notified dmac=00:09:0f:09:1e:03 cs1Label=sname cs1=Trojan.Gen.C.DNS ``` ## 참고 문헌 아래의 경로에서 원문 (영문)을 확인할 수 있습니다. * [ArcSight Common Event Format (CEF) Guide](https://www.protect724.hpe.com/servlet/JiveServlet/downloadBody/1072-102-9-20354/CommonEventFormatv23.pdf)

2017-03-25

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