
비글(Beagle)은 보안 로그와 데이터를 그래프로 변환하는 사고 대응 및 디지털 포렌식 도구입니다.
Beagle은 데이터 소스와 로그를 그래프로 변환하는 침해 대응 및 디지털 포렌식 도구입니다. 지원되는 데이터 소스로는 FireEye HX Triage, Windows EVTX 파일, SysMon 로그 및 원시 Windows 메모리 이미지가 있습니다. 생성된 그래프는 Neo4J 또는 DGraph와 같은 그래프 데이터베이스로 전송하거나 로컬에서 Python NetworkX 객체로 유지할 수 있습니다.
Beagle은 Python 라이브러리로 직접 사용하거나 제공되는 웹 인터페이스를 통해 사용할 수 있습니다.
라이브러리는 단일 데이터 소스에서 일련의 함수 호출로 사용할 수 있습니다.
>>> from beagle.datasources import SysmonEVTX
>>> graph = SysmonEVTX("malicious.evtx").to_graph()
>>> graph
<networkx.classes.multidigraph.MultiDiGraph at 0x12700ee10>
여러 아티팩트 집합에서 생성된 그래프로도 사용할 수 있습니다.
>>> from beagle.datasources import SysmonEVTX, HXTriage, PCAP
>>> from beagle.backends import NetworkX
>>> nx = NetworkX.from_datasources(
datasources=[
SysmonEVTX("malicious.evtx"),
HXTriage("alert.mans"),
PCAP("traffic.pcap"),
]
)
>>> G = nx.graph()
<networkx.classes.multidigraph.MultiDiGraph at 0x12700ee10>
또는 데이터 소스에서 그래프까지의 각 중간 단계를 엄격하게 호출할 수도 있습니다.
>>> from beagle.backends import NetworkX
>>> from beagle.datasources import SysmonEVTX
>>> from beagle.transformers import SysmonTransformer
>>> datasource = SysmonEVTX("malicious.evtx")
# Transformers take a datasource, and transform each event
# into a tuple of one or more nodes.
>>> transformer = SysmonTransformer(datasource=datasource)
>>> nodes = transformer.run()
# Transformers output an array of nodes.
[
(<SysMonProc> process_guid="{0ad3e319-0c16-59c8-0000-0010d47d0000}"),
(<File> host="DESKTOP-2C3IQHO" full_path="C:\Windows\System32\services.exe"),
...
]
# Backends take the nodes, and transform them into graphs
>>> backend = NetworkX(nodes=nodes)
>>> G = backend.graph()
<networkx.classes.multidigraph.MultiDiGraph at 0x126b887f0>
그래프는 개별 프로세스의 활동을 중심으로 구성되며, 주로 분석가가 호스트 간이 아닌 호스트 내 활동을 조사하는 데 도움을 주기 위한 것입니다.
Beagle은 Docker 파일로 제공됩니다.
docker pull yampelo/beagle
mkdir -p data/beagle
docker run -v "$PWD/data/beagle":"/data/beagle" -p 8000:8000 yampelo/beagle
라이브러리로도 사용할 수 있습니다. 전체 API 문서는 https://beagle-graphs.readthedocs.io에서 확인할 수 있습니다.
pip install pybeagle
참고: 현재 Python 3.6+만 지원됩니다.
Rekall은 자동으로 설치되지 않습니다. Rekall을 설치하려면 다음 명령어를 대신 실행하세요.
pip install pybeagle[rekall]
설정 파일의 모든 항목은 BEAGLE__{SECTION}__{KEY} 형식을 따르는 환경 변수를 사용하여 수정할 수 있습니다. 예를 들어, Docker 이미지를 사용할 때 VirusTotal API 키를 변경하려면 -e 매개변수를 사용하여 BEAGLE__VIRUSTOTAL__API_KEY 변수를 설정하면 됩니다.
docker run -v "data/beagle":"/data/beagle" -p 8000:8000 -e "BEAGLE__VIRUSTOTAL__API_KEY=$API_KEY" beagle
환경 변수와 디렉터리는 docker compose를 사용하여 쉽게 정의할 수 있습니다.
version: "3"
services:
beagle:
image: yampelo/beagle
volumes:
- /data/beagle:/data/beagle
ports:
- "8000:8000"
environment:
- BEAGLE__VIRUSTOTAL__API_KEY=$key$
Beagle의 Docker 이미지에는 데이터를 그래프로 변환하는 과정과 이를 사용하여 데이터를 조사하는 과정을 모두 포함하는 웹 인터페이스가 함께 제공됩니다.
업로드 양식은 그래프 생성 과정을 감싸며 자동으로 NetworkX를 백엔드로 사용합니다. 데이터 소스에 필요한 매개변수에 따라 양식은 파일 업로드 또는 텍스트 입력을 요구합니다. 예를 들어:
생성된 그래프는 설정의 storage 섹션에 있는 dir 키로 정의된 폴더에 로컬로 저장됩니다. 이는 BEAGLE__STORAGE__DIR 환경 변수를 설정하여 수정할 수 있습니다.
선택적으로 그래프에 설명을 추가하여 더 잘 식별할 수 있습니다.
각 데이터 소스는 제공된 매개변수에서 자동으로 메타데이터를 추출합니다. 메타데이터와 설명은 나중에 해당 데이터 소스의 기존 그래프를 볼 때 표시됩니다.
사이드바에서 데이터 소스를 클릭하면 해당 데이터 소스에 대해 분석된 모든 그래프의 테이블이 표시됩니다.
Beagle에서 그래프를 보면 분석가가 사건을 신속하게 피벗할 수 있는 웹 인터페이스가 제공됩니다.
인터페이스는 두 부분으로 나뉩니다. 왼쪽에는 그래프의 다양한 관점(그래프, 트리, 테이블 등)이 있고, 오른쪽에는 유형별로 노드와 엣지를 필터링하고, 노드를 검색하며, 노드의 속성을 확장할 수 있습니다. 또한 그래프에 수행한 작업을 실행 취소 및 재실행할 수 있습니다.
그래프에서 위에 구분선이 있는 요소는 접을 수 있습니다.
그래프의 노드는 특정 필드의 처음 15자를 표시합니다. 예를 들어 프로세스 노드의 경우 프로세스 이름이 표시됩니다.
엣지는 단순히 엣지 유형을 표시합니다.
노드 또는 엣지를 한 번 클릭하면 해당 요소가 선택되고 오른쪽 사이드바의 "노드 정보" 패널에 정보가 표시됩니다.
노드를 더블 클릭하면 인접 노드가 가져와집니다. 인접 노드는 클릭한 노드와 엣지로 연결된 모든 노드입니다. 가져올 이웃이 없으면 그래프에 변화가 없습니다.
노드를 길게 한 번 클릭하면 해당 노드와 이에 의존하는 모든 엣지가 그래프에서 숨겨집니다.
노드를 마우스 오른쪽 버튼으로 클릭하면 그래프 mutators를 실행할 수 있는 컨텍스트 메뉴가 나타납니다. Mutators는 그래프 상태를 받아 새 상태를 반환하는 함수입니다.
매우 유용한 두 가지 mutators는 다음과 같습니다.
노드 역추적은 매우 유용하며 로그 파일에서 근본 원인 감염을 수행하는 것과 유사합니다.
노드의 하위 항목을 확장하면 이 노드로 인해 발생한 모든 것을 즉시 볼 수 있습니다. 이 작업은 선택한 노드를 루트로 하는 부분 그래프를 표시합니다.
때로는 노드 또는 엣지가 현재 사건과 관련이 없을 수 있습니다. 엣지 및 노드 유형을 켜고 끌 수 있습니다. 유형이 전환되면 해당 유형의 노드나 엣지가 표시되는 그래프에서 제거됩니다.
노드 유형을 끄면 mutators를 사용하거나 이웃을 가져올 때 해당 노드 유형이 사용되지 않습니다.
그래프의 모든 작업은 즉시 되돌릴 수 있습니다! 실행 취소/재실행 버튼을 사용하여 수행한 작업을 되돌릴 수 있습니다. 초기화 버튼은 그래프 상태를 로드 당시로 설정하여 새로 고침을 절약합니다.
위 작업을 사용하여 그래프의 현재 상태를 변경할 때, 다른 관점에서 현재 표시되는 노드 및 엣지 집합을 보고 싶을 수도 있습니다. 그래프 화면 상단의 탭을 사용하면 데이터를 다양한 보기로 변환할 수 있습니다.
각 관점은 노드를 클릭하여 포커스하는 것을 지원합니다.
그래프 생성 과정은 Python 라이브러리를 사용하여 프로그래밍 방식으로 수행할 수 있습니다. 그래프 생성 과정은 세 단계로 구성됩니다.
DataSource 클래스는 이벤트를 하나씩 파싱하고 생성합니다.Transformer 클래스는 이러한 입력을 받아 Process와 같은 다양한 Node 클래스로 변환합니다.Backend 클래스는 노드 배열을 가져와 그래프 구조에 배치하고 원하는 위치로 보냅니다.Python 패키지는 pip를 통해 설치할 수 있습니다.
pip install pybeagle
그래프를 생성하려면 이들을 연결해야 합니다. to_graph() 함수를 사용하면 자동으로 처리됩니다.
from beagle.datasources import HXTriage
# By default, using the to_graph() class uses NetworkX and the first transformer.
G = HXTriage('test.mans').to_graph()
<networkx.classes.multidigraph.MultiDiGraph at 0x12700ee10>
각 단계를 명시적으로 수행할 수도 있습니다. 함수 호출을 사용하여 예를 들어 DGraph로 데이터를 보내기 위해 사용할 백엔드를 정의할 수도 있습니다.
from beagle.datasources import HXTriage
from beagle.backends import DGraph
from beagle.transformers import FireEyeHXTransformer
# The data will be sent to the DGraph instance configured in the
# configuration file
backend = HXTriage('test.mans').to_graph(backend=DGraph)
# Can also specify the transformer
backend = HXTriage('test.mans').to_transformer(transformer=FireEyeHXTransformer).to_graph(backend=DGraph)
to_graph 또는 to_transformer 메서드를 호출할 때 해당 클래스에 인수를 전달할 수 있습니다.
from beagle.datasources import HXTriage
from beagle.backends import Graphistry
# Send the graphistry, anonymize the data first, and return the URL
graphistry_url = HXTriage('test.mans').to_graph(backend=Graphistry, anonymize=True, render=False)
위 과정의 각 단계를 수동으로 호출하여 중간 출력물에 접근할 수도 있습니다.
>>> from beagle.backends import NetworkX
>>> from beagle.datasources import HXTriage
>>> from beagle.transformers import FireEyeHXTransformer
>>> datasource = HXTriage("test.mans")
>>> transformer = FireEyeHXTransformer(datasource=datasource)
>>> nodes = transformer.run()
>>> backend = NetworkX(nodes=nodes)
>>> G = backend.graph()
각 단계를 수동으로 호출하려면 Transformer 클래스 인스턴스가 제공된 DataSource 클래스의 출력과 호환되는지 확인해야 합니다.
각 데이터 소스는 호환되는 Transformer 목록을 정의하며, 이는 .transformers 속성을 통해 접근할 수 있습니다.
>>> from beagle.datasources import HXTriage
>>> HXTriage.transformers
[beagle.transformers.fireeye_hx_transformer.FireEyeHXTransformer]
기본적으로 엣지는 압축되지 않습니다. 즉, 프로세스 노드 u가 파일 노드 v에 5000번 쓰기를 수행하면 두 노드 사이에 5000개의 엣지가 생깁니다. 때로는 특히 데이터를 시각화하려고 할 때 분석가에게 부담이 될 수 있습니다.
백엔드 클래스에 consolidate_edges=True 매개변수를 전달하면 5000개의 엣지를 해당 작업 유형(이 경우 wrote)에 대해 하나의 엣지로 압축할 수 있습니다. 예를 들어:
SysmonEVTX("data/sysmon/autoruns-sysmon.evtx").to_graph(NetworkX, consolidate_edges=False)
# Graph contains 826 nodes and 2469 edges.
SysmonEVTX("data/sysmon/autoruns-sysmon.evtx").to_graph(NetworkX, consolidate_edges=True)
# Graph contains 826 nodes and 1396 edges
웹 인터페이스는 기본적으로 엣지를 압축합니다.
NetworkX 백엔드를 사용하면 결과 그래프를 JSON 객체로 저장하여 나중에 사용할 수 있습니다. NetworkX.from_json 정적 메서드를 사용하여 다시 로드할 수 있습니다.
import json
from beagle.datasources import SysmonEVTX
from beagle.backends import NetworkX
# Get back a nx.MultiDiGraph object
graph = SysmonEVTX("malicious.evtx").to_graph()
# Convert the object to JSON
graph_json = NetworkX.graph_to_json(graph)
with open("my_graph.json", "w") as f:
json.dump(graph_json, f)
# Later on:
# G is the same nx.MultiDiGraph object generated by `.to_graph()`
G = NetworkX.from_json("my_graph.json")