AI가 생성한 사이버 공격 재구성의 타당성 검증
요약
Cyber Autopsy는 AI가 파편화된 사이버 포렌식 보고서로부터 공격을 재구성할 때 추측과 사실을 명확히 구분하도록 설계된 벤치마크 시스템입니다. 이 도구는 구조화된 콘텐츠 계층(Sanity)과 관계 그래프를 활용하여 증거-사건-주장 간의 복잡한 관계를 시각화합니다. 이를 통해 분석가들은 출처와 불확실성을 추적하며 정확하고 검증 가능한 인시던트 타임라인을 구축할 수 있습니다.
핵심 포인트
- AI 기반 재구성 과정의 신뢰성 평가 벤치마크 제공
- Evidence, Event, Claim 간의 관계를 구조화하여 시각화
- 출처(provenance)와 불확실성을 추적하는 포렌식 조사 콘솔 구현
- 전통적인 서술 요약 대신 검증 가능한 인시던트 타임라인 생성
_이 글은 Sanity Challenge, Path One: 실제 콘텐츠를 질의하는 에이전트 배포에 제출하는 내용입니다.
제가 구축한 것
Cyber Autopsy는 사건에 대해 구조화된 질문을 던지는 사이버 포렌식 조사실입니다: 무슨 일이 일어났는지, 그 이전에 무엇이 있었는지, 어떤 증거가 이를 뒷받침하는지, 아직 알려지지 않은 것은 무엇인지, 그리고 특정 시점에 알 수 있었던 정보는 무엇이었는지 등을 다룹니다.
이 프로젝트는 AI가 파편화된 보고서로부터 공격을 재구성할 때 추측을 사실처럼 제시하지 못하게 평가하기 위한 Kaggle 스타일의 벤치마크로 시작되었습니다. 저는 여기에 구조화된 콘텐츠 계층인 Sanity, MCP 호환 조사 서버, 그리고 포렌식 테마 웹 인터페이스를 추가했습니다.
핵심 모델은 조사를 유용하게 만드는 관계들을 보존합니다:
Evidence ──supports──> Event ──precedes/enables/causes──> Event
Evidence ──supports/contradicts──> Claim
UI는 각 사례를 작은 조사 콘솔로 제시합니다. 조사관들은 특정 사례를 선택하고, 사건 설명을 읽고, 질문을 던지며, 재구성, 관계 그래프, 불확실성 목록, 모순되는 주장, 그리고 출처 출신(source provenance)이 있는 확장 가능한 증거 등 결과를 검사할 수 있습니다.
이것이 사이버 보안 조사에 도움이 되는 이유
사이버 포렌식 오토십티는 증거 재구성 문제입니다. 분석가들은 완벽한 타임라인을 받는 경우가 거의 없습니다. 대신 인증 로그, 엔드포인트 관찰 기록, 위협 보고서, 분석가 메모, 부정적 발견 사항, 그리고 경쟁하는 주장들을 받습니다. 어려운 부분은 그것들이 무엇을 입증하는지 과장하지 않으면서 이 조각들이 어떻게 관련되는지를 결정하는 것입니다.
Cyber Autopsy는 Sanity를 사용하여 해당 추론 과정을 검사 가능하게 만듭니다. 분석가는 이벤트가 근거 증거로 연결되는 경로를 따라가고, 공격 그래프를 이동하며, 특정 주장이 모순되는지 확인하고, '확인됨(confirmed)', '추론됨(inferred)', '시도됨(attempted)', 그리고 '알 수 없음(unknown)'을 구별할 수 있습니다. 이는 다음 상황에 유용합니다:
- 초기 접근(initial access), 측면 이동(lateral movement), 지속성 확보(persistence), 데이터 유출(exfiltration), 영향(impact) 재구성
- 모든 것을 서술적 요약으로 평탄화하는 대신 출처(provenance)를 유지하는 인시던트 타임라인 생성
- 조사관이 'Day 1' 시점까지 무엇을 알 수 있었는지 테스트
- 다른 행위자(actor)의 관점에서 동일한 증거 비교
- 분석가 교육 및 보정된 불확실성(calibrated uncertainty)에 대한 에이전트 평가
그 결과는 일반적인 검색 상자라기보다는 디지털 인시던트 부검에 가깝습니다. 시스템은 증거의 사슬, 기록상의 공백, 그리고 각 결론을 둘러싼 추론 경계를 보존합니다.
데모 (Demo)
프로젝트를 로컬에서 실행하세요:
npm run dev
그런 다음 http://localhost:3000을 여세요.
코드 (Code)
저장소에는 Python 벤치마크, Sanity Studio, 가져오기(importer), MCP 서버, 로컬 UI, 테스트 및 문서가 포함되어 있습니다.
Repository: [https://github.com/ujjavala/cyber-autopsy]
가장 관련성이 높은 구현 파일은 다음과 같습니다:
studio-cyber-autopsy/schemaTypes/index.ts Sanity 콘텐츠 모델
scripts/sanity-seed.mjs 반복 가능한 JSONL 가져오기
agent/sanity-context.mjs 범위 지정된 GROQ 조사 컨텍스트
...
Sanity를 사용한 방법 (How I Used Sanity)
Sanity가 도움을 준 방법 (How Sanity helped)
Sanity는 이 벤치마크의 조사 그래프를 위해 지속 가능하고 쿼리 가능한 콘텐츠 계층을 제공했습니다. 통합 이전에는 데이터셋이 주로 로컬 JSONL 파일 그룹이었습니다. 이는 재현은 가능했지만, 에이전트(agent), 스튜디오(Studio), 브라우저 UI 전반에 걸쳐 콘텐츠를 검사(inspect), 연결(connect), 재사용하기 어렵게 만들었습니다.
Sanity를 사용하면서 동일한 조사 콘텐츠가 연결된 문서(linked documents)로 모델링되었습니다. 증거(Evidence), 사건(events), 주장(claims), 관계(relationships), 사고(incidents), 출처(sources)는 독립적으로 쿼리되거나 함께 순회(traversed)될 수 있습니다. 이는 네 가지 실질적인 방식으로 도움이 되었습니다:
- 근거 기반 (Grounding): 에이전트는 느슨한 텍스트 검색에 의존하는 대신, 사례와 관련된 정확한 증거 및 관계를 검색합니다.
- 추적 가능성 (Traceability): 모든 결과는 증거 및 출처의 출처(provenance)로 되돌아갈 수 있어 분석가의 검토가 가능하게 합니다.
- 범위 제어 (Scope control): 쿼리 계층에서 사례별 참조 및 차단 규칙을 적용하여, 나중의 사실이 초기 재구성으로 유출되는 것을 방지할 수 있습니다.
- 재사용 (Reuse): 동일한 구조화된 콘텐츠가 Sanity Studio, MCP 서버, 자동화 테스트(automated tests), 포렌식 UI(forensic UI)에 동력을 제공합니다.
따라서 Sanity는 조사 지식 기반(investigation knowledge base) 역할을 하며, 컨텍스트 계층(context layer)은 추론 경계(reasoning boundary) 역할을 합니다. 에이전트에게 사건을 기억하거나 타임라인을 발명하라고 요구하는 것이 아니라, 구조화된 콘텐츠를 쿼리하고 보정된 재구성(calibrated reconstruction)을 반환하도록 합니다.
Sanity에서 상세히 사용된 기능
1. 구조화된 문서 스키마
하나의 대규모 사고 문서로 저장하는 대신, 저는 조사를 개별적인 문서 유형으로 모델링했습니다. 이는 포렌식 분석가가 작업하는 방식과 일치합니다. 즉, incident는 사건 맥락이며, evidence는 관찰 기록이고, event는 재구성 기록이며, claim은 주장(assertion)이고, relationship은 두 이벤트가 어떻게 연결되는지를 설명합니다.
이러한 분리는 각 정보 유형에 명확한 검증 및 쿼리 경계를 제공합니다. 예를 들어, event에는 상태(status)와 신뢰도(confidence)가 포함되며, evidence 문서에는 타임스탬프(timestamp), 관찰 유형(observation type), 엔티티(entities), 소스 참조(source references)가 있습니다. relationship은 원본 이벤트(source event), 대상 이벤트(target event), 관계 유형(relation type), 그리고 이를 뒷받침하는 증거(supporting evidence)를 가집니다.
2. 참조 및 그래프 형태의 콘텐츠
여기서 가장 중요한 Sanity 기능은 참조(reference) 필드입니다. evidence는 이벤트의 텍스트를 복사하지 않으며, relationship 역시 두 이벤트 기록을 모두 복사하지 않습니다. 대신 이들은 표준 문서(canonical documents)를 가리킵니다:
defineField({
name: 'sourceEvent',
type: 'reference',
...
이것은 Sanity를 탐색 가능한 조사 그래프로 만듭니다. 에이전트는 case -> incident -> event -> evidence -> source 순서로 이동할 수 있으며, 동일한 인시던트에 대해 별도로 relationship 및 claim 문서를 검색할 수 있습니다. 사용자 인터페이스(UI)에서는 이것이 지원되지 않는 단락 대신, 가시적인 출처(provenance)를 갖춘 재구성 기록으로 나타납니다.
3. 필드 검증 및 제어된 상태
Studio 스키마는 필수 식별자 및 참조를 검증하고, 신뢰도를 0..1 범위로 제한하며, 증거와 이벤트 상태에 대해 제어된 옵션을 사용합니다. 사용 가능한 상태 분류법(taxonomy)은 의도적으로 포렌식적입니다:
confirmed · inferred · attempted · failed · unknown
또한 claim은 contradicted(모순됨)를 지원합니다. 이러한 값들은 UI에서 확립된 사실과 불확실하거나 실패한 단계를 분리하는 데 사용됩니다. 이는 누락된 관찰 기록이 조용히 확인된 이벤트가 되는 것을 방지하고, 측정 가능한 불확실성(calibrated uncertainty)을 콘텐츠 모델의 일부로 만듭니다.
4. GROQ 프로젝션 및 역참조(dereferencing)
컨텍스트 레이어는 GROQ 프로젝션을 사용하여 조사에 필요한 필드만 요청합니다. -> 연산자는 관련 문서를 역참조(dereference)하여 브라우저가 개별 기록마다 요청을 보내지 않아도 하나의 응답 안에 케이스, 인시던트 요약, 증거 및 소스 메타데이터를 포함할 수 있게 합니다.
예를 들어, 케이스 쿼리는 인시던트를 투영하고 그 증거와 이벤트를 결합합니다:
*[_type == "investigationCase" && caseId == $caseId][0] {
caseId, mode, temporalCutoff, framingActor,
incident->{incidentId, title, description, actor, impact},
...
이는 응답이 구조화된 상태를 유지하기 때문에 보안 분석에 유용합니다. 에이전트는 산문에서 그러한 구분을 복구하려고 시도하는 대신 타임스탬프, 상태, 증거 ID 및 관계 유형별로 필터링할 수 있습니다.
5. 매개변수화되고 범위가 지정된 쿼리 (Parameterized, scoped queries)
쿼리는 caseId와 incidentRef로 매개변수화됩니다. 선택된 케이스는 보이는 증거 세트를 정의하고, 컨텍스트는 이벤트를 반환하기 전에 허용되는 증거 ID 세트를 파생합니다. 관계는 그 지원 증거와 양쪽 끝점 이벤트가 범위(scope) 안에 있을 때만 포함됩니다.
이것이 구현체가 시간적 안전성을 처리하는 방식입니다. CASE-004는 단순히 UI의 레이블이 아닙니다. 이의 Sanity 참조가 증거 경계를 정의합니다. 'Day 1' 질문은 결과가 렌더링되기 전에 추가적인 D1 필터를 적용할 수도 있습니다. 모델은 나중에 발생한 랜섬웨어 이벤트를 마치 Day 1에 알려진 것처럼 실수로 인용할 수 없습니다.
6. Sanity Content API
노드 컨텍스트는 프로젝트 ID, 데이터셋, GROQ 쿼리 및 선택적 서버 측 토큰을 사용하여 Sanity의 Content API를 사용합니다. 이 토큰은 서버에서 .env 파일로부터 로드되며 브라우저에 절대 노출되지 않습니다. 브라우저는 로컬 웹 서버와 통신하고, 로컬 서버가 Sanity와 통신합니다.
이러한 분리는 프로젝트에 더 안전한 구조를 제공합니다:
Browser UI → local investigation API → Sanity Content API
^
서버 측 토큰
동일한 API 경계는 실패 사례도 명시적으로 만듭니다. 누락된 경우(missing case)에는 명확한 오류가 발생하고, 빈 증거 세트(empty evidence set)는 클라이언트 측 length 예외를 유발하는 대신 빈 조사 범위로 처리됩니다.
7. Sanity Studio, 구조 도구 및 Vision
이 프로젝트에는 동일한 프로젝트와 production 데이터셋을 위해 구성된 독립형 Sanity Studio가 포함되어 있습니다. 구조 도구(Structure Tool)는 일곱 가지 문서 유형에 대한 편집 작업 공간을 제공하며, 미리보기에서는 CASE-004, E-021과 같은 유용한 포렌식 식별자 또는 이벤트 설명을 보여줍니다.
Vision 도구는 Studio 내에서 GROQ를 직접 검사하고 테스트할 수 있도록 활성화되어 있습니다. 이는 조사 쿼리를 개발할 때 유용합니다: MCP 컨텍스트에 연결하기 전에 케이스 투영(case projection)을 확인하고, 참조(references)를 검사하며, 실제 데이터셋에 대해 커트오프 쿼리(cutoff query)를 테스트할 수 있습니다.
8. 트랜잭션적 변경 및 반복 가능한 가져오기
가져오기 도구는 수백 개의 문서를 수동으로 편집하는 대신 Sanity 뮤테이션(mutations)을 배치로 사용합니다. 이는 의존성 순서에 따라 정규화된 문서들을 생성하거나 대체한 다음, 증거-이벤트(evidence-to-event), 증거-클레임(evidence-to-claim), 그리고 모순 링크(contradiction links)를 위한 역참조 패치(reverse-reference patches)를 적용합니다.
가져오기는 반복 가능하고 테스트할 수 있습니다:
npm run sanity:validate # 소스 인벤토리 검증
node scripts/sanity-seed.mjs --dry-run
npm run sanity:seed # 콘텐츠를 Sanity에 작성
이는 벤치마크에 재현 가능한 마이그레이션 경로를 제공하는 동시에, 라이브 지식 기반을 Studio에서 편집 가능하게 유지합니다. 또한 스키마가 나중에 다른 포렌식 필드를 얻더라도 데이터셋을 다시 구축할 수 있다는 의미입니다.
9. MCP를 에이전트 경계로 사용하기
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기



