I let a local 27B LLM audit and fix my Splunk + Sysmon stack
로컬 27B LLM에게 내 Splunk + Sysmon 스택의 감사와 수정을 맡겼다
보안 분석가가 자신의 16GB GPU에서 동작하는 로컬 27B LLM 에이전트에게 Splunk + Sysmon 홈 SOC의 감사와 자동 복구를 맡긴 실험기입니다. 이중 수집, 죽은 데이터 입력, LSASS 접근 탐지 누락 등 실제 문제를 찾아 고쳤고, 과정에서 컨텍스트 관리와 시스템 프롬프트 설계의 중요성을 구체적인 수치로 보여줍니다.
- 주제
본문
CySA+ 자격증을 준비 중인 보안 분석가인 저자는 SOC 경험이 없어 홈 SOC를 직접 구축해 연습하고 있었고, '데이터가 한 바이트도 외부로 나가지 않는 로컬 LLM이 Splunk 설치를 감사하고 스스로 고칠 수 있는가'라는 질문을 검증했습니다. 답은 '몇 가지 주의할 점과 함께 가능하다'였고, 저자는 실패 사례까지 포함해 기록했습니다.
16GB GPU 위의 27B SOC 분석가
환경은 세 가지로 구성됐습니다. SIEM인 Splunk(개발 라이선스), 엔드포인트 텔레메트리인 Sysmon, 그리고 단일 16GB GPU에서 llama-server로 서빙되는 양자화된 Qwen3.8-27B(IQ2_M, Gated DeltaNet 하이브리드, 128K 컨텍스트)입니다. 목표는 설명해주는 멘토가 아니라 실제 설치를 감사하고 설정을 수정·명령을 제안하는 에이전트였습니다. 저자는 설정 검사, 데이터 파이프라인 리뷰, 로깅 하드닝, 24시간 로그 분석, IoC 탐지 등 다섯 차례 실전 감사를 수행한 뒤 수정 권한을 넘겼습니다. 모델은 시니어 분석가처럼 추론해 저자의 잘못된 가정을 세 번 바로잡았고, 답을 모를 때 지어내는 대신 '확인할 수 없다'고 말했습니다.
모델이 찾아낸 실제 문제들
첫 번째는 이중 수집이었습니다. 인덱서가 로컬에서 로그를 수집하는데 같은 머신의 Universal Forwarder가 같은 로그를 다시 보내 라이선스 사용량과 노이즈가 두 배였습니다. 모델은 MSI 레지스트리의 두 제품 GUID를 읽고 어떤 것을 제거해야 하고 어떤 것은 절대 건드리면 안 되는지 명시했는데, 후자는 모든 데이터가 담긴 Splunk 본체였습니다. 잘못된 msiexec /x 한 번이면 랩 전체가 날아가는 상황이었습니다. 또 msiexec /x ... /qn이 비동기 동작 때문에 -1이라는 유령 종료 코드를 반환했고, Start-Process msiexec -Wait -PassThru로 바꿔야 ExitCode 0과 함께 서비스·디렉터리·레지스트리가 깨끗이 제거됐습니다.
설치일부터 죽어 있던 세 개의 데이터 입력도 발견됐습니다. 두 개는 Windows 이벤트 채널 자체가 비활성화돼 읽을 로그가 없었고, 세 번째는 이중 버그였습니다. 필수 파라미터 누락에 더해, 스페인어 Windows에서 성능 카운터가 영어로 설정돼 있었던 것입니다. 스페인어 환경에서는 '% Processor Time'이 아니라 '% de tiempo de procesador'이며 객체 이름까지 현지화됩니다. 해결책은 도구가 영어 API를 쓰도록 강제하는 것이었고, 모델은 설정 수정 후에도 바이너리가 샘플링에서 죽자 '성공'이 아니라 '바이너리 디버깅 필요'로 기록했습니다.
Sysmon은 LSASS 접근에 눈이 멀어 있었습니다. LSASS는 메모리에 크리덴셜을 보관하는 프로세스로 Mimikatz의 표적이며, 저자의 설정으로는 크리덴셜 덤프를 탐지하지 못했습니다. lsass.exe를 대상으로 한 ProcessAccess 필터는 세 줄짜리 수정이지만, 과정에서 모델과 저자 모두 잘못된 Sysmon 이벤트 ID 매핑을 기억하고 있었다는 것이 드러났습니다. 실제 설정 파일이 이를 반박했고, '기술적인 숫자는 기억이 아니라 실물과 대조해야 한다'는 교훈이 남았습니다. 프로세스 생성 로깅을 켜는 auditpol 명령 하나에도 세 함정이 있었습니다. 권한 부족, 카테고리 이름 현지화, PowerShell에서 중괄호 GUID가 따옴표 없이는 문법을 깨는 문제입니다. 그리고 기존 발견 두 건은 오탐이었는데, 이를 잡아낸 것도 모델이었습니다. '비활성화'로 기록된 채널은 실제로 수백 건의 이벤트를 기록 중이었고(원래 감사가 잘못된 채널을 봤음), 사용자 프로필의 임시 파일을 건드리는 모든 프로세스를 위협으로 표시한 탐지 규칙은 코드 에디터와 노트 앱, AI 에이전트 자신까지 적으로 만들어 Electron 예외 처리가 필요했습니다.
컨텍스트는 낭비하면 안 된다
감사에서의 철저함은 복구에서는 독이었습니다. 첫 수정 작업에서 모델은 성능 카운터 도구로 검증하고 벤더 스펙을 읽고 실패하는 바이너리를 수동 실행하는 전면 포렌식을 펼치다가, 수정과 무관한 Windows Update 로그의 소스 이름을 쫓으며 128K 컨텍스트의 97.4%를 소진했습니다. 답은 알고 있었지만 멈출 줄 몰랐던 것입니다. 저자는 temperature를 0.8에서 0.3으로 낮추고 '질문에만 답할 것, 복구 시 근거 있는 근본 원인에서 멈출 것, 감사 시에는 철저할 것, 기계적 작업은 스크립트로, ID·포트·GUID는 확인 후 주장할 것, 지어내지 말 것' 같은 작업 규칙 시스템 프롬프트를 추가했습니다. 결과는 컨텍스트 사용률 97.4%에서 49.7%로, '30분에 발견 1건'에서 '연속 4건'으로 바뀌었습니다.
열 건의 발견과 교훈
열 건의 발견 중 이중 수집 해결, 입력 두 건 수정(한 건은 바이너리 디버깅 보류), 크리덴셜 접근 탐지 추가, 프로세스 로깅 활성화, 오탐 두 건 정정까지 이뤄졌습니다. 완벽한 결과가 아니기에 오히려 보고서를 신뢰할 수 있다고 저자는 말합니다. 남은 교훈은 이렇습니다. 27B 로컬 모델은 이미 이 작업을 할 만큼 유능하며 병목은 지능이 아니라 컨텍스트입니다. 감사에는 철저함을 요구하고 복구에는 그것을 금지해야 합니다. 기계적 작업은 스크립트에 맡겨야 합니다 — 123KB 설정 파일에 두 줄 넣으라고 시켰더니 30분을 들여 전체 파일을 손으로 재생성했습니다. 그리고 결정론적 동작은 모델의 속성이 아니라 설정 선택의 문제라는 것입니다. LLM은 판단력을 대체하지 않지만, 잠들지도 머신을 떠나지도 않는 멘토로서 입문자에게는 실질적인 이점이라고 저자는 결론 내립니다.
원문: dev.to / 번역·요약: Trawling