전체 아키텍처
┌──────────────────────────────────────────────┐ │ Hermes Agent │ │ (작업 스케줄링, 메모리 관리, 도구 실행 제어) │ ├──────────────────────────────────────────────┤ │ MCP 서비스 계층 │ │ ├── recon-tools (로컬 노드 프로세스) │ │ │ ├── fofa_query / shodan_query / ... │ │ │ ├── hunter_query (3개 키 교체 사용) │ │ │ └── port_scanner (DISABLE_SCAN 설정 시 비활성) │ │ ├── kali-remote (SSH를 통한 Kali 명령 실행) │ │ │ └── shodan-cli / masscan / sqlmap / ...│ │ └── threat-intel (로컬 Python 프로세스) │ │ └── ip_analysis / domain_check / ... │ ├──────────────────────────────────────────────┤ │ 프로필 계층 │ │ ├── recon/ (정보 수집가 - 수동 정찰) │ │ │ config.yaml: kali-remote=off, DISABLE_SCAN=true│ │ │ ROLE.md: "스캔 없이 정보 수집만 수행" │ │ │ skills: passive-recon-workflow │ │ ├── active-recon/ (적극 정찰가 - 전체 기능) │ │ ├── researcher/ (보안분석가 - 분석 전용) │ │ ├── default/ (표준 공격자 - 모든 도구) │ │ ├── hw-attacker/ (HW 공격자 - 증명 후 중단) │ │ ├── reporter/ (보고서 작성자 - 문서화) │ │ └── ir-analyst/ (사고 대응 전문가 - 위협 추적)│ ├──────────────────────────────────────────────┤ │ hermes-webui (독립 Python 프로세스, 포트 8787)│ │ ├── state.db에서 CLI 세션 읽기 │ │ └── WebUI 세션 저장 위치: ~/.hermes/webui/sessions/│ └──────────────────────────────────────────────┘
작업 처리 흐름
정보 수집가 프로필에서 "A 기관의 공개 자산 조회" 요청 시:
- WebUI → Hermes Agent로 메시지 전달
- Agent가 recon 프로필 설정 로드:
- ROLE.md → "수동 정찰만 수행"
- config.yaml → kali-remote=off, port_scanner 비활성
- LLM에 역할 설정과 메시지 전달
- LLM이 fofa_query 도구 호출 요청
- Agent가 recon-tools MCP의 fofa_query 실행
- FOFA API로 HTTPS 요청 전송 및 결과 반환
- LLM이 결과 분석 후 사용자에게 출력
핵심: Agent는 FOFA/nmap을 인지하지 못하며, 프로필의 config.yaml이 허용하는 도구만 사용 가능
프로필 물리적 분리 구현
// recon-tools/index.js 내 포트 스캐너 제어
if (action === "port_scanner") {
if (process.env.DISABLE_SCAN === "enabled") {
return "[포트 스캔] HW 작업에서는 FOFA/Shodan으로 대체";
}
// 정상 실행 로직
}
recon의 config.yaml에 DISABLE_SCAN: "enabled" 설정으로 LLM의 무단 스캔 시도 차단
측정 플랫폼 통합 구조
5개 플랫폼을 recon-tools MCP에 통합 구현:
LLM: fofa_query, query="domain=example.co.kr" ↓ Hermes → stdio로 JSON 전송 ↓ recon-tools에서 fofa_query 핸들러 실행 ↓ https://fofa.info/api/v1 호출 ↓ 결과 반환 → LLM → 사용자
WebUI 배포 절차
WSL2 Ubuntu 환경에서 실행:
git clone https://github.com/nesquena/hermes-webui.git /opt/hermes-webui cd /opt/hermes-webui HERMES_WEBUI_AGENT_DIR=/usr/lib/hermes-agent \ HERMES_WEBUI_PYTHON=/usr/lib/hermes-agent/venv/bin/python \ python3 bootstrap.py
systemd 서비스 등록:
[Unit] Description=Hermes WebUI After=network.target [Service] Type=simple Environment=HERMES_WEBUI_PORT=8787 WorkingDirectory=/opt/hermes-webui ExecStart=/usr/lib/hermes-agent/venv/bin/python server.py Restart=always [Install] WantedBy=multi-user.target
프로필 기반 역할 구성
정보 수집가(recon) 설정 예시:
# ROLE.md ## 역할 정책 - FOFA/Shodan/Hunter를 통한 자산 검색 - DNS 레코드 분석 - 인증서 투명성 로그 기반 서브도메인 탐지 - HTTP 헤더 지문 분석 - WHOIS 쿼리 ## 절대 금지 사항 1. 포트 스캔 실행 금지 2. 취약점 탐지 시도 금지
config.yaml 수정:
mcp_servers:
kali-remote:
enabled: false
recon-tools:
env:
DISABLE_SCAN: "enabled"
FOFA_KEY: "key_value"
HUNTER_KEYS: "key1,key2,key3"
MCP 도구 추가 방법
새 플랫폼(Hunter) 연동:
// 도구 정의
{
name: "hunter_query",
description: "Hunter API를 통한 자산 검색",
parameters: {
search: { type: "string", desc: "검색 쿼리" },
count: { type: "number", default: 15 }
}
}
// API 호출 로직
const apiKeys = process.env.HUNTER_KEYS.split(",");
for (const key of apiKeys) {
const queryEnc = Buffer.from(params.search).toString('base64');
const response = await fetch(`https://hunter.example.com/search?key=${key}&q=${queryEnc}`);
if (response.status === 200) break;
}
ThreatBook MCP 연동
로컬 파이썬 서비스 구성:
threat-intel:
type: local
command: /usr/bin/python3
args: ["/path/to/threatmcp.py"]
env:
THREATBOOK_API: "your_api_key"
제공 기능: ip_analysis, domain_check, file_scan 등 19개 도구
실전 적용 시나리오
HW 기간 정보 수집
- recon 프로필로 대상 도메인 조회
- recon-tools로 다중 플랫폼 병렬 검색
- 분석 필요 시 researcher 프로필 전환
CTF 대회 문제 해결
- active-recon으로 전체 포트 스캔
- default 프로필에서 취약점별 공격 실행
- reporter로 결과 보고서 생성
주요 기술 팁
- curl 사용 시 응답 헤더/본문 분리 확인:
curl -s -D headers.txt -o body.txt - 동일 공격 방식 3회 실패 시 전략 전환
- 웹 파라미터 시도: user, account, token, auth, session, id