Autoruns를 이용한 악성코드 지속성 분석
개요
Sysinternals Autoruns는 Windows의 수백 가지 자동 시작 확장 지점(ASEP)에서 데이터를 추출하며, Run/RunOnce 키, 서비스, 예약 작업, 드라이버, Winlogon 항목, LSA 공급자, 프린트 모니터, WMI 구독, AppInit DLL 등 18개 이상의 카테고리를 스캔합니다. 디지털 서명 확인으로 Microsoft 서명 항목을 필터링합니다. 비교 함수는 기준선 차이(baseline diffing)를 통해 새로 추가된 지속성 메커니즘을 식별합니다. VirusTotal 통합으로 해시 평판을 확인합니다. -z 플래그를 통한 오프라인 분석으로 포렌식 디스크 이미지 검사도 가능합니다.
사용 시기
- 악성코드 지속성을 분석해야 하는 보안 사고 조사 시
- 이 도메인에 대한 탐지 규칙 또는 위협 헌팅 쿼리 작성 시
- SOC 분석가가 이 분석 유형에 대한 구조화된 절차가 필요할 때
- 관련 공격 기술에 대한 보안 모니터링 적용 범위를 검증할 때
사전 요구 사항
- Sysinternals Autoruns (GUI) 및 Autorunsc (CLI)
- 대상 시스템에 대한 관리자 권한
- 자동화된 분석을 위한 Python 3.9+
- 평판 확인을 위한 VirusTotal API 키
- 비교를 위한 깨끗한 기준선 내보내기
작업 흐름
1단계: 자동화된 지속성 스캔
#!/usr/bin/env python3
"""Autoruns 기반 지속성 분석 자동화."""
import subprocess
import csv
import json
import sys
def scan_and_analyze(autorunsc_path="autorunsc64.exe", csv_path="scan.csv"):
cmd = [autorunsc_path, "-a", "*", "-c", "-h", "-s", "-nobanner", "*"]
result = subprocess.run(cmd, capture_output=True, text=True, timeout=600)
with open(csv_path, 'w') as f:
f.write(result.stdout)
return parse_and_flag(csv_path)
def parse_and_flag(csv_path):
suspicious = []
with open(csv_path, 'r', errors='replace') as f:
for row in csv.DictReader(f):
reasons = []
signer = row.get("Signer", "")
if not signer or signer == "(Not verified)":
reasons.append("서명되지 않은 바이너리")
if not row.get("Description") and not row.get("Company"):
reasons.append("메타데이터 누락")
path = row.get("Image Path", "").lower()
for sp in ["\temp\", "\appdata\local\temp", "\users\public\"]:
if sp in path:
reasons.append(f"의심스러운 경로")
launch = row.get("Launch String", "").lower()
for kw in ["powershell", "cmd /c", "wscript", "mshta", "regsvr32"]:
if kw in launch:
reasons.append(f"LOLBin: {kw}")
if reasons:
row["reasons"] = reasons
suspicious.append(row)
return suspicious
if __name__ == "__main__":
if len(sys.argv) > 1:
results = parse_and_flag(sys.argv[1])
print(f"[!] {len(results)}개의 의심스러운 항목 발견")
for r in results:
print(f" {r.get('Entry','')} - {r.get('Image Path','')}")
for reason in r.get('reasons', []):
print(f" - {reason}")
검증 기준
- 모든 ASEP 카테고리가 스캔되고 분류되어야 함
- 서명되지 않은 항목이 조사를 위해 플래그 지정되어야 함
- 의심스러운 경로 및 LOLBin 실행 문자열이 강조되어야 함
- 기준선 비교를 통해 새로운 지속성 메커니즘을 식별해야 함