
런타임 취약점 스캐너: 호스트에서 실제 실행 중인 서비스의 CVE를 찾아 네트워크 노출도에 따라 순위를 매깁니다.
threat-finder는 호스트에서 실제로 실행 중인 취약한 소프트웨어를 찾아냅니다. 매니페스트가 주장하는 내용이 아니라 실제 실행 중인 것을 기준으로 하며, 어떤 발견 항목이 네트워크로 도달 가능한지도 알려줍니다. 각 실행 중인 서비스(--scope all을 사용하면 설치된 모든 OS 패키지)를 정확한 Package-URL로 해석한 다음, OffSeq Radar 카탈로그와 에코시스템 고유 버전 규칙을 사용하여 매칭하므로 백포트되거나 수정된 빌드가 오탐(false-positive)으로 플래그되지 않습니다.
Vulnerability summary (highest risk first):
openssh-server@1:8.9p1-3ubuntu0.6 — 1 finding(s) [PUBLIC tcp 0.0.0.0:22]
[ACT-NOW 92] HIGH CVE-2024-6387 [KEV] regreSSHion: remote code execution in OpenSSH
→ fix: 1:8.9p1-3ubuntu0.10 https://radar.offseq.com/threat/…
[email protected] — 1 finding(s)
[SCHEDULE 41] MED CVE-2023-44487 HTTP/2 Rapid Reset
2 confirmed finding(s) across 2 asset(s); 1 exposed, 1 known-exploited.
brew install offseq/tap/threat-finder # Homebrew (macOS/Linux), prebuilt
cargo binstall threat-finder # prebuilt binary, no toolchain
cargo install threat-finder # from source
Linux/macOS(x86_64 + arm64) 및 Windows(x86_64)용 사전 빌드 아카이브는 릴리스 페이지에서 다운로드할 수 있습니다. 소스에서 빌드하려면 Rust ≥ 1.87이 필요합니다. Linux, macOS, BSD 계열 및 Windows를 모두 지원합니다.
export OFFSEQ_API_KEY=... # from https://radar.offseq.com/console
threat-finder
실행 중인 서비스를 스캔하고, 위험도 순으로 정렬된 요약을 출력하며, 전체 JSON 보고서를 /tmp/threats.json에 기록합니다. --scope all을 추가하면 설치된 모든 OS 패키지도 스캔합니다.
threat-finder [OPTIONS]
| Flag | 설명 |
|---|---|
-o, --output <PATH> | JSON 보고서를 PATH에 기록합니다(기본값: 프롬프트 또는 /tmp/threats.json) |
--json | 파일 대신 stdout으로 JSON 보고서를 출력합니다 |
--scope <SCOPE> | running(기본값) 또는 all(+ 설치된 모든 OS 패키지) |
--severity <LEVEL> | critical|high|medium|low 이상의 심각도 발견 항목만 보고합니다 |
--strict | 좌표 미확인 발견 항목을 제외합니다(확인된 항목만 보고) |
--fail-on <WHAT> | 일치하는 발견 항목이 있으면 5로 종료합니다: any|critical|high|medium|low|kev|exposed |
--sarif <PATH> | SARIF 2.1.0 보고서도 기록합니다(코드 스캐닝 UI용) |
--include <GLOB> / --exclude <GLOB> | 이름 글로브로 자산을 필터링합니다(반복 가능) |
-q, --quiet | 배너, 진행 상황 및 요약을 숨깁니다 |
--no-color | ANSI 색상을 비활성화합니다 |
-y, --yes | 기본값을 사용하고 프롬프트를 표시하지 않습니다(CI/cron) |
--reset | 저장된 키를 무시하고 API 키를 다시 입력합니다 |
--register | 지속적 모니터링을 위해 스캔한 호스트를 Radar에 등록합니다(프롬프트 없음) |
--no-register | 이번 실행에서 모니터링 등록을 하지 않거나 등록을 묻지 않습니다 |
--host-name <NAME> | 등록 시 함께 보낼 알아보기 쉬운 호스트 이름 |
--unregister | 이 호스트의 인벤토리를 Radar에서 제거하고 종료합니다 |
--windows-missing-updates | (Windows) Windows Update Agent의 보류 중인 보안 업데이트도 나열합니다(온라인 스캔, 관리자 권한으로 실행) |
-h, --help / -V, --version | 도움말 / 버전 |
# CI: only high+ findings, JSON to stdout, no prompts
OFFSEQ_API_KEY=… threat-finder --yes --json --severity high > report.json
# Fail the build only when a network-exposed service has a known-exploited CVE
OFFSEQ_API_KEY=… threat-finder --yes --quiet --fail-on exposed
종료 코드: 0 정상 · 1 조회/IO 오류 · 2 API 키 없음 · 3 지원되지 않는 OS · 4 속도 제한/할당량 초과 또는 API 액세스 필요(업그레이드 필요) · 5 --fail-on 임계값 충족
API 키 (Radar Console에서 발급)는 다음 순서로 확인됩니다:
OFFSEQ_API_KEY 환경 변수(CI/cron에 가장 적합).--reset이 제공되지 않은 경우 $XDG_CONFIG_HOME/offseq-rust/config.toml(0600)에 저장된 키.키를 사용할 수 없는 비대화형(--yes / TTY 없음) 실행은 2로 종료됩니다.
OFFSEQ_CONFIG_DIR을 설정하면 구성 파일 위치를 재정의할 수 있습니다(기본값: OS 사용자별 구성 디렉터리). 결정적 경로가 필요한 컨테이너/CI에 유용합니다.
정확한 좌표 매칭. 각 자산은 전체 버전(에포크 + 배포판 리비전)과 ?distro= 한정자를 포함하는 purl이 됩니다(예: pkg:deb/ubuntu/openssh-server@1:8.9p1-3ubuntu0.6?distro=jammy). 인벤토리는 일괄 POST /match/batch 호출(티어 크기 청크당 하나의 요청)로 서버 측에서 에코시스템 고유 버전 규칙(dpkg/rpm/apk/semver)을 사용하여 매칭됩니다. 따라서 1.18.0-6+deb11u3처럼 백포트되어 수정된 빌드는 올바르게 플래그되지 않으며, 클라이언트 측 버전 추측도 없습니다. 발견 항목은 API의 confirmed 플래그에 따라 구분됩니다: 확인된 매칭은 보고되고, 버전을 확인할 수 없는 좌표 매칭은 unconfirmed / triage로 별도 표시됩니다(개수, byCve, --fail-on에서 제외되며 --strict로 제거할 수 있습니다).
네트워크 노출 상관관계. 매니페스트 스캐너(Trivy, Grype, osv-scanner)는 패키지 목록을 읽습니다. 외부 스캐너(Nessus, OpenVAS)는 두 번째 호스트가 필요합니다. 이 도구는 각 실행 중인 서비스의 프로세스를 해당 서비스가 리스닝 중인 소켓(Linux의 /proc/net, 기타 Unix의 lsof, Windows의 Get-NetTCPConnection / netstat)에 매핑하고 도달 가능성을 loopback / private / public으로 분류합니다. 0.0.0.0에서 실행 중인 취약한 서비스는 127.0.0.1에서 실행 중인 서비스와는 매우 다른 위험을 의미합니다. 발견 항목은 노출된 항목이 먼저 순위가 매겨지며 --fail-on exposed는 정확히 이를 기준으로 CI를 게이트합니다. 패킷은 전송되지 않습니다. 발견 항목에는 CISA KEV 및 EPSS도 포함됩니다.
노출 인식 우선순위 지정. 모든 발견 항목은 심각도, EPSS, KEV 및 소유 자산의 네트워크 노출을 융합하여 riskScore(0–100)와 SSVC 스타일의 decision 밴드 — act-now · soon · schedule · track — 를 받습니다. 요약은 각 줄을 [ACT-NOW 92] 스타일 배지로 시작하고 이 값으로 정렬하므로, 공개적으로 노출되고 알려진 악용 문제 몇 건이 시끄러운 호스트의 맨 위로 떠오릅니다. 점수는 로컬과 서버 측에서 동일한 공식을 사용합니다(Radar 모니터링 보기는 KEV 발견 항목이 기한을 지난 경우 작은 보너스를 추가합니다 — CLI에는 없는 날짜). 이 점수는 --json 및 SARIF(properties)에도 나타납니다.
일회성 스캔은 특정 시점의 스냅샷입니다. 호스트를 한 번 등록하면 Radar가 계속 감시합니다. 새로 게시된 CVE가 해당 좌표 중 하나에 영향을 미치면 노출 우선순위에 따라 알림(이메일 + Console)을 받습니다. 재스캔이 필요 없습니다.
대화형 스캔 후 도구는 다음과 같이 묻습니다:
Add these 42 services to Radar for continuous monitoring & alerts? [Y/n/never]
Y는 이 호스트를 등록하고, n은 이번 실행을 건너뛰며, never는 선택을 기억합니다(구성에 저장되며 다시 묻지 않습니다). 재스캔 시 드리프트(+added / -removed / ~changed)와 마지막 스캔 이후 새로 발견된 항목도 보고합니다. Radar Console의 Inventory에서 호스트를 관리할 수 있습니다 — 모니터링 토글, 발견 항목 보기, 등록 해제.
자동화를 위해 프롬프트를 건너뛸 수 있습니다: --register는 비대화형으로 등록하고(CI에서는 기본적으로 꺼짐), --no-register는 등록을 거부하며, --host-name <NAME>은 호스트에 이름을 지정하고, --unregister는 등록을 제거합니다. 호스트당 안정적인 ID와 프롬프트 기본 설정은 $XDG_CONFIG_HOME/offseq-rust/config.toml에 저장됩니다. 등록은 종료 코드를 변경하지 않습니다 — 모니터링 문제가 스캔을 실패시키지 않습니다. Basic/Pro/Enterprise 요금제(또는 Pro Console)가 필요합니다.
--scope running(기본값)은 노출 상관관계를 파악할 수 있는 작고 신호 대비 효과가 높은 실행 중인 서비스를 스캔합니다. --scope all은 추가로 설치된 모든 OS 패키지(dpkg/rpm/pacman/apk/brew/pkg/pkg_info)를 열거하여 매칭 대상을 10–50배 확장합니다. 실행 중이고 노출된 프로세스를 뒷받침하는 패키지도 해당 노출을 유지합니다(자산은 좌표별로 중복 제거되고 병합됩니다). 커널은 --scope all에서 해당 패키지(linux-image…)로 포함됩니다.
--scope all은 수백에서 수천 개의 패키지를 생성할 수 있습니다. 무료 티어(시간당 15회 조회)에서는 속도 제한이 발생할 수 있으며, 도구는 인벤토리가 예산을 초과하면 경고합니다. (조회는 이미 일괄 처리됩니다. 로컬 결과 캐시는 로드맵에 있습니다.)
| OS | 검색 | 좌표 소스 |
|---|---|---|
| Linux (systemd) | ListUnits → /proc/<pid>/exe | dpkg / rpm / pacman / apk |
| Linux (SysV/OpenRC) | service --status-all / rc-status | 패키지 DB |
| macOS | launchctl list → ps(타사 전용) | Homebrew |
| FreeBSD / DragonFly | service -e | pkg |
| OpenBSD | rcctl ls started | pkg_info |
| NetBSD | /etc/rc.d status | pkg_info |
| Solaris / illumos | svcs → svcprop | 프로브(--version) |
| Windows | Win32_Service → Get-NetTCPConnection / netstat | registry / winget / Appx / Chocolatey / Scoop → CPE; npm / pip / dotnet → purl; the OS build → CPE |
어떤 패키지도 바이너리를 소유하지 않은 경우 버전은 강화된 --version 프로브(절대 경로만, 환경 변수는 삭제됨)로 폴백됩니다. macOS에서는 Apple 시스템 서비스(com.apple.*, SIP 보호 경로)를 건너뜁니다. OS 버전으로 이미 처리되며, 수백 개를 프로빙하는 것은 의미가 없기 때문입니다.
Windows에서는 모든 정보가 기본 제공되는 powershell.exe를 통해 수집됩니다(추가 런타임 불필요, 핵심 인벤토리에 관리자 권한 불필요). 설치된 앱은 큐레이팅된 이름 테이블을 통해 NVD CPE로 매핑됩니다(매핑되지 않은 앱은 잘못된 추측 대신 이름 검색으로 폴백). OS 에디션/빌드는 기능 한정자를 갖춘 OS CPE가 됩니다(예: windows_11_23h2). --windows-missing-updates는 운영자 선택 방식으로 Windows Update Agent의 보류 중인 보안 패치 권고를 추가합니다.
JSON은 결정적(정렬된) 키와 타임스탬프 없이 생성되므로 보고서를 깔끔하게 diff할 수 있습니다:
services — pkg@version → 확인된 발견 항목(cveId, severity, cvssScore, epss, kev, riskScore, decision, confirmed, matchedRange, matchBasis, fixedVersions, remediation, cwes, references, radarUrl), 위험도 높은 순.unconfirmed — 버전을 확인할 수 없는 좌표 매칭(트리아지).assets — pkg@version → { exe, versionSource, exposed, reachability, listeners }(versionSource = package-db | probe; reachability는 TCP 및 UDP를 포함).byCve — 각 CVE를 영향을 받는 모든 자산에 걸쳐 집계합니다("한 번 패치하면 여러 곳이 해결").errors — 자산별 조회 실패를 나타내므로 실패가 "깨끗함"으로 오인되지 않습니다.registration — 실행이 호스트를 등록한 경우 표시됩니다: host_id, monitoring, drift, summary, newSinceLastCount.meta — { tool, version, schemaVersion }(schemaVersion 2).코드 스캐닝 UI용 SARIF 2.1.0 보고서(--sarif)도 사용할 수 있습니다.
| OffSeq | EU 보안 감사, 위협 모니터링, CISO-as-a-Service, NIS2 컴플라이언스 |
| Radar | 실시간 위협 인텔리전스 — threat-finder가 매칭하는 카탈로그 |
| Radar Console | 구독, 맞춤 피드 및 사용자의 OFFSEQ_API_KEY |
| Radar API | 여기서 사용하는 /match 엔드포인트용 REST 문서 |
| Radar Threats | 검색 가능한 CVE / 악성코드 / 위협 행위자 데이터베이스 |
| Radar Feeds | CISA, CIRCL, ThreatFox 등을 집계하는 맞춤 피드 |
| Radar Pricing | 무료 티어부터 엔터프라이즈까지 |
| Breach | 다크웹 데이터 유출 및 노출된 자격 증명 모니터링 |
| Veil | 클라이언트 측 PNG 스테가노그래피(AES-256-GCM) |
| Guard | AI 웹사이트 보안 및 컴플라이언스 분석기 |
| Training | PECB 인증 보안 및 개인정보 보호 과정 |
cargo build --release
cargo test # unit tests
cargo test -- --ignored # + macOS live-discovery smoke test
cargo clippy --all-targets
엔진은 Collector 추상화를 갖춘 라이브러리 크레이트(find_threats)입니다(현재는 실행 중인 서비스와 OS 패키지, 다음에는 lockfile / 컨테이너 / SBOM). 따라서 바이너리는 그 위에 있는 얇은 CLI입니다.
MIT 또는 Apache-2.0에 따라 이중 라이선스가 적용되며, 선택할 수 있습니다.