본문 바로가기
운영체제 (LNX,WIN)

Windows 보안 센터와 WSC Provider로 기업 맞춤형 보안 체커 탑재 방법

by 날으는물고기 2025. 9. 3.

Windows 보안 센터와 WSC Provider로 기업 맞춤형 보안 체커 탑재 방법

728x90

윈도우 보안 센터(Windows Security Center, WSC)는 Microsoft가 윈도우 운영체제 내에서 보안 제품(백신, 방화벽, 스파이웨어 방지 도구 등)의 상태를 모니터링하기 위해 제공하는 모듈입니다. 여기에 회사 내부에서 만든 보안 체커(예: 취약점 점검기, 에이전트 등)를 정식 Provider로 등록하면 Windows 보안 센터에서 다른 보안 제품처럼 상태를 인식하고 표시할 수 있습니다.

1. 기본 배경

  • WMI(Windows Management Instrumentation)Security Center API 를 통해 보안 소프트웨어의 상태를 보안 센터에 보고할 수 있습니다.
  • Microsoft는 보안 공급자(Security Provider) 타입을 크게 4가지로 나눕니다.
    • AntiVirus
    • AntiSpyware
    • Firewall
    • Internet Security Settings / User Account Control (UAC) / Windows Update
  • Windows 보안 센터는 이 API를 통해 등록된 보안 공급자의 상태를 모니터링하고 사용자 UI에 노출합니다.

2. 구현 방법

(1) COM API 활용

  • IWscProduct 인터페이스를 사용해 보안 제품의 상태를 등록할 수 있습니다.
  • Provider는 상태(Status: On, Off, Snoozed 등)와 서명 업데이트 상태를 보고해야 합니다.

 

예시 C++ 코드 스니펫

#include <wscapi.h>

HRESULT hr;
IWscProduct* pProduct = NULL;
hr = CoCreateInstance(__uuidof(WscProduct), NULL, CLSCTX_INPROC_SERVER, IID_IWscProduct, (LPVOID*)&pProduct);

if (SUCCEEDED(hr)) {
    WSC_SECURITY_PRODUCT_STATE state = WSC_SECURITY_PRODUCT_STATE_ON;
    WSC_SECURITY_SIGNATURE_STATUS sigStatus = WSC_SECURITY_PRODUCT_UP_TO_DATE;

    pProduct->put_ProductName(L"MyCompany Security Checker");
    pProduct->put_ProductState(state);
    pProduct->put_SignatureStatus(sigStatus);

    pProduct->Release();
}

(2) WMI Provider 등록

  • WSC는 WMI 클래스(AntiVirusProduct, FirewallProduct 등)를 통해 보안 공급자의 상태를 가져갑니다.
  • 내부 보안 체커를 WMI Provider로 구현하고, 레지스트리에 CLSID를 등록해야 합니다.
300x250

레지스트리 경로 예시

HKLM\SOFTWARE\Microsoft\Security Center\Provider\{GUID}

3. 보안 가이드

회사의 내부 보안 체커를 윈도우 보안 센터에 등록할 때 고려해야 할 점

  1. 권한 관리
    • 로컬 SYSTEM 권한으로 동작해야만 보안 센터와 연동 가능.
    • 잘못된 권한 설정 시 우회나 악성코드가 보안 제품을 가장할 위험 존재.
  2. 무결성 검증
    • 자체 보안 체커 바이너리에 서명 코드(Code Signing)를 적용.
    • Microsoft의 ELAM(Early Launch Anti-Malware) 구조 참고.
  3. 상태 보고 주기
    • 일정 주기로 보안 상태(예: 취약점 점검 결과, 패치 적용 여부)를 보안 센터에 업데이트.
    • 미보고 시 Windows 보안 센터에서 “보호되지 않음”으로 표시됨.
  4. 로그/감사
    • 이벤트 로그(Event Viewer → Applications and Services Logs → Microsoft → Windows → Security Center) 에 상태 기록.
    • 보안팀은 이를 중앙 SIEM과 연계하여 모니터링 가능.

4. 활용 사례

  • 백신 이외의 회사 전용 체커 등록
    • 예: 내부 취약점 점검기(패치 미적용 여부, 레지스트리 보안 설정 점검기 등)를 Antivirus Provider처럼 등록.
  • 엔드포인트 보안 표준화
    • Windows 보안 센터에서 모든 보안 도구의 상태를 일원화해 사용자와 보안팀 모두 한눈에 확인 가능.
  • 중앙 모니터링
    • SCCM, Intune, SIEM과 연동 시 내부 체커의 상태도 함께 수집 가능.

내부 보안 체커 WSC 등록 절차

1. 보안 공급자(Security Provider) GUID 생성

  • 보안 센터에 등록할 때 고유한 GUID가 필요합니다.
  • PowerShell에서 GUID 생성
    [guid]::NewGuid()
  • 예시 출력
    f2a7b2e4-2a7c-4c56-9d3c-54aa8a0f1a77

2. 레지스트리 등록

  • 경로
    HKLM\SOFTWARE\Microsoft\Security Center\Provider\{GUID}
  • 필수 값 예시 (Antivirus Provider로 등록)
    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Security Center\Provider\{f2a7b2e4-2a7c-4c56-9d3c-54aa8a0f1a77}]
    "DisplayName"="MyCompany Security Checker"
    "Company"="MyCompany Inc."
    "Path"="C:\\Program Files\\MyCompany\\checker.exe"
    "ProductState"=dword:00000010   ; 상태 (예: 0x10 = 활성화)
    "Timestamp"=hex(b):00,00,00,00,00,00,00,00
    "SignatureStatus"=dword:00000000 ; 0=최신, 1=구버전
    "Type"=dword:00000001            ; 1=Antivirus, 2=Firewall, 3=Antispyware
  • 주요 키 설명
    • DisplayName : 보안 센터에 표시될 이름
    • Path : 실행 파일 위치
    • ProductState : 동작 상태 (활성/비활성)
    • SignatureStatus : 보안 점검 결과 최신 여부
    • Type : Provider 종류

3. WMI Provider 구현 (선택적)

  • 고급 구현 방식은 WMI 클래스(AntiVirusProduct, FirewallProduct)를 직접 작성해서 상태 보고.
  • 보안 센터는 WMI를 통해 제품 상태를 가져오기 때문에, 내부 체커는 점검 결과를 WMI에 주기적으로 업데이트해야 함.
  • 예시 WMI 클래스 (MOF 파일)
    class AntiVirusProduct : WMIBase {
      [key] string instanceGuid;
      string displayName;
      string pathToSignedProductExe;
      uint32 productState;
    };

4. 상태 보고 자동화

  • 보안 체커가 실행될 때마다 점검 결과를 WSC에 업데이트.
  • 간단하게는 reg add 명령어로 갱신 가능
    reg add "HKLM\SOFTWARE\Microsoft\Security Center\Provider\{f2a7b2e4-2a7c-4c56-9d3c-54aa8a0f1a77}" /v ProductState /t REG_DWORD /d 0x10 /f
  • 고급 방식은 WSC API (IWscProduct 인터페이스) 를 통해 COM 호출.

테스트 방법

1. 보안 센터 UI 확인

  • Windows 보안보호 영역바이러스 및 위협 방지 메뉴에서 등록 여부 확인.
  • “MyCompany Security Checker”가 나타나야 함.

2. WMI 쿼리 확인

Get-CimInstance -Namespace root/SecurityCenter2 -ClassName AntivirusProduct

출력 예시

displayName       : MyCompany Security Checker
productState      : 16
pathToSignedExe   : C:\Program Files\MyCompany\checker.exe

3. 이벤트 로그 확인

  • Event Viewer → Applications and Services Logs → Microsoft → Windows → Security Center
  • 상태 변경 이벤트가 기록되는지 확인.

보안 점검 포인트

  1. 코드 서명: 내부 체커 실행 파일은 반드시 코드 서명(CA 인증서) 적용.
  2. 무결성 보호: 악성코드가 Provider로 위장하지 못하도록 CLSID/GUID 관리 필요.
  3. 업데이트 정책: 주기적으로 ProductState와 SignatureStatus 값 갱신.
  4. 중앙 모니터링: 이벤트 로그를 SIEM/EDR로 전송해 관리.

👉 요약하면,

  • 레지스트리 등록 + WMI 클래스 구현을 통해 WSC에 내부 체커를 공급자로 등록할 수 있고,
  • 점검 결과를 ProductState 값으로 주기적 갱신하면 Windows 보안 센터에서 자동 반영됩니다.

 

아래는 회사 내부 보안 체커를 Windows 보안 센터(Windows Security Center, WSC)에 “공급자 형태”로 탑재하는 자동화 스크립트운영/검증/보안 가이드입니다.

⚠️주의: 실제로 WSC에 “정식 공급자”로 인식되려면 보통 네이티브 서비스/COM 구성 + 코드서명 + WSC API 연동(IWscProduct 등) 이 필요합니다. 레지스트리만으로는 모든 윈도우 버전에서 완전하게 동작하지 않을 수 있습니다(특히 최신 Win10/11). 아래 스크립트는 POC/파일럿 또는 운영 자동화 관점으로 제공하며, 정식 상용 통합 시에는 C/C++(또는 C# COM Interop)로 WSC API를 호출하는 서비스 구성(아래 보안/확장 섹션 참고)을 병행해 주세요.

PowerShell 자동화 스크립트 (POC/파일럿)

  • 기능
    1. 공급자 GUID 생성 및 레지스트리 등록
    2. 내부 체커 실행 경로 등록
    3. 스케줄러(Task Scheduler)로 주기 실행 및 결과를 ProductState/SignatureStatus로 갱신
    4. 검증용 쿼리/로그 수집
    5. 제거(rollback) 스크립트 포함

1. 변수/전역 설정

# 관리자 권한 PowerShell 권장
# 실행 정책(필요 시): Set-ExecutionPolicy RemoteSigned -Scope Process

# === 사용자 환경에 맞게 수정 ===
$VendorName       = "MyCompany Inc."
$ProductName      = "MyCompany Security Checker"
$CheckerExe       = "C:\Program Files\MyCompany\checker.exe"   # 내부 체커 실행 파일
$CheckerArgs      = ""                                         # 체커 인자(필요 시)
$ScheduleMinutes  = 15                                         # 점검 주기(분)
$ProviderType     = 1                                          # 1=Antivirus, 2=Firewall, 3=Antispyware (POC용 매핑)
$LogName          = "Application"
$EventSource      = "MyCompanySecurityChecker"
$RegBase          = "HKLM:\SOFTWARE\Microsoft\Security Center\Provider"

# === GUID: 고정 사용 시 주석 해제 ===
# $ProviderGuid   = "{f2a7b2e4-2a7c-4c56-9d3c-54aa8a0f1a77}"

# 새 GUID 생성(기본)
if (-not $ProviderGuid) { $ProviderGuid = ("{" + [guid]::NewGuid().ToString() + "}") }

Write-Host "Using Provider GUID: $ProviderGuid"

2. 전제 체크(파일/권한/이벤트 소스)

# 체커 파일 존재 여부
if (-not (Test-Path $CheckerExe)) {
    Write-Error "체커 실행 파일이 존재하지 않습니다: $CheckerExe"
    throw
}

# 관리자 권한 확인
$curr = [Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()
if (-not $curr.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
    Write-Error "관리자 권한으로 PowerShell을 실행해 주세요."
    throw
}

# 이벤트 소스 등록(없으면 생성)
if (-not [System.Diagnostics.EventLog]::SourceExists($EventSource)) {
    New-EventLog -LogName $LogName -Source $EventSource
}

3. 레지스트리 등록(POC용)

$RegPath = Join-Path $RegBase $ProviderGuid.Trim('{}')

New-Item -Path $RegPath -Force | Out-Null

New-ItemProperty -Path $RegPath -Name "DisplayName"     -Value $ProductName -PropertyType String -Force | Out-Null
New-ItemProperty -Path $RegPath -Name "Company"         -Value $VendorName  -PropertyType String -Force | Out-Null
New-ItemProperty -Path $RegPath -Name "Path"            -Value $CheckerExe  -PropertyType String -Force | Out-Null
New-ItemProperty -Path $RegPath -Name "Type"            -Value $ProviderType -PropertyType DWord -Force | Out-Null

# 초기 상태(활성/최신으로 가정): ProductState / SignatureStatus
# ProductState 예시: 0x10(16)=ON, 0x00=OFF, 0x20(32)=Snoozed 등 (POC 단순화)
# SignatureStatus: 0=UpToDate, 1=OutOfDate
New-ItemProperty -Path $RegPath -Name "ProductState"     -Value 0x10 -PropertyType DWord -Force | Out-Null
New-ItemProperty -Path $RegPath -Name "SignatureStatus"  -Value 0    -PropertyType DWord -Force | Out-Null

# 타임스탬프(바이너리; POC에선 0)
New-ItemProperty -Path $RegPath -Name "Timestamp" -Value ([byte[]](0..7 | ForEach-Object {0})) -PropertyType Binary -Force | Out-Null

Write-EventLog -LogName $LogName -Source $EventSource -EntryType Information -EventId 1000 -Message "WSC Provider 레지스트리 등록 완료: $RegPath"
Write-Host "레지스트리 등록 완료: $RegPath"

4. 체커 결과 → 상태 매핑 함수

# 체커가 0=정상, 1=위험, 2=경고 형태로 종료코드를 반환한다고 가정
function Convert-ExitCodeToWsc {
    param([int]$code)
    switch ($code) {
        0 { return @{ ProductState = 0x10; SignatureStatus = 0 } } # ON, 최신
        1 { return @{ ProductState = 0x00; SignatureStatus = 1 } } # OFF, 구버전(문제)
        2 { return @{ ProductState = 0x20; SignatureStatus = 1 } } # Snoozed/주의
        default { return @{ ProductState = 0x00; SignatureStatus = 1 } }
    }
}

5. 상태 갱신 스크립트(작업 스케줄러가 실행할 대상)

$UpdateScriptPath = "$env:ProgramData\MyCompany\WSC-Update.ps1"
$null = New-Item -ItemType Directory -Path (Split-Path $UpdateScriptPath) -Force

@"
param(
    [string]\$RegPath,
    [string]\$CheckerExe,
    [string]\$CheckerArgs,
    [string]\$LogName,
    [string]\$EventSource
)

# 체커 실행
\$p = Start-Process -FilePath \$CheckerExe -ArgumentList \$CheckerArgs -NoNewWindow -PassThru -Wait
\$exit = \$p.ExitCode

# 상태 매핑(간단화를 위해 내부 함수 재정의)
function Convert-ExitCodeToWsc {
    param([int]\$code)
    switch (\$code) {
        0 { return @{ ProductState = 0x10; SignatureStatus = 0 } }
        1 { return @{ ProductState = 0x00; SignatureStatus = 1 } }
        2 { return @{ ProductState = 0x20; SignatureStatus = 1 } }
        default { return @{ ProductState = 0x00; SignatureStatus = 1 } }
    }
}

\$m = Convert-ExitCodeToWsc -code \$exit

# 레지스트리 업데이트
New-ItemProperty -Path \$RegPath -Name "ProductState"    -Value \$m.ProductState   -PropertyType DWord -Force | Out-Null
New-ItemProperty -Path \$RegPath -Name "SignatureStatus" -Value \$m.SignatureStatus -PropertyType DWord -Force | Out-Null

Write-EventLog -LogName \$LogName -Source \$EventSource -EntryType Information -EventId 1100 -Message "체커 실행 종료코드=\$exit, ProductState=\$($m.ProductState), SignatureStatus=\$($m.SignatureStatus)"

exit 0
"@ | Set-Content -Path $UpdateScriptPath -Encoding UTF8

Write-Host "상태 갱신 스크립트 생성: $UpdateScriptPath"

6. 작업 스케줄러 등록(주기 실행)

$TaskName = "MyCompany-SecurityChecker-Update"
$Action   = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-NoProfile -ExecutionPolicy Bypass -File `"$UpdateScriptPath`" -RegPath `"$RegPath`" -CheckerExe `"$CheckerExe`" -CheckerArgs `"$CheckerArgs`" -LogName `"$LogName`" -EventSource `"$EventSource`""
$Trigger  = New-ScheduledTaskTrigger -Once -At (Get-Date).AddMinutes(1) -RepetitionInterval (New-TimeSpan -Minutes $ScheduleMinutes) -RepetitionDuration ([TimeSpan]::MaxValue)
$Principal= New-ScheduledTaskPrincipal -UserId "SYSTEM" -RunLevel Highest

Register-ScheduledTask -TaskName $TaskName -Action $Action -Trigger $Trigger -Principal $Principal -Force

Write-EventLog -LogName $LogName -Source $EventSource -EntryType Information -EventId 1200 -Message "작업 스케줄러 등록 완료: $TaskName (매 $ScheduleMinutes 분)"
Write-Host "작업 스케줄러 등록 완료: $TaskName (매 $ScheduleMinutes 분)"

7. 검증(즉시 1회 실행)

Start-ScheduledTask -TaskName $TaskName
Start-Sleep -Seconds 3

# 레지스트리 값 확인
Get-ItemProperty -Path $RegPath | Select-Object DisplayName,Company,Path,Type,ProductState,SignatureStatus

동작 확인(검증 시나리오)

  1. Windows 보안 UI
    • Windows 보안 → 보호 영역(바이러스 및 위협 방지 등)에서 노출 여부 확인
    • (주의) 레지스트리 POC만으로는 일부 버전에서 UI 반영이 제한될 수 있습니다.
  2. WMI 쿼리
    • 보통 root/SecurityCenter2 네임스페이스의 AntivirusProduct 등에서 조회됩니다.
    • POC 레지스트리만으로는 즉시 반영되지 않거나 표시되지 않을 수 있습니다.
    • 확인 명령
      Get-CimInstance -Namespace root/SecurityCenter2 -ClassName AntivirusProduct |
        Select-Object displayName,productState,pathToSignedProductExe
  3. 이벤트 로그
    • 이벤트 뷰어 → Windows Logs → Application
    • Source=MyCompanySecurityChecker 로 정보 이벤트(1000,1100,1200) 확인
  4. 스케줄러
    Get-ScheduledTask -TaskName "MyCompany-SecurityChecker-Update" | Get-ScheduledTaskInfo

제거(롤백) 스크립트

# 제거 시에도 관리자 권한 필요
$TaskName   = "MyCompany-SecurityChecker-Update"
$RegBase    = "HKLM:\SOFTWARE\Microsoft\Security Center\Provider"
$ProviderGuid = "<위에서 사용한 GUID>"   # 예: {f2a7b2e4-...}

try {
    Unregister-ScheduledTask -TaskName $TaskName -Confirm:$false
} catch {}

$RegPath = Join-Path $RegBase $ProviderGuid.Trim('{}')
if (Test-Path $RegPath) {
    Remove-Item $RegPath -Recurse -Force
}

Write-Host "제거 완료"

실무 적용 포인트

  1. 코드 서명 필수
    • 체커 실행 파일 및(정식 통합 시) COM/서비스 바이너리는 코드서명 하세요.
    • 서명 무결성 검사를 배포 파이프라인/런타임에서 수행(서명자, 유효기간, 해시 등 검증).
  2. 권한 최소화
    • 작업 스케줄러는 SYSTEM으로 돌려도 되지만, 체커 자체 작업은 최소권한 원칙 적용.
    • 체커가 관리자 권한을 필요로 하는지, 왜 필요한지 문서화.
  3. 상태 기준 정의
    • 종료코드 매핑(0=정상, 1=위험, 2=경고 등)과 “최신/구버전”의 정의를 명시.
    • 예: 시그니처/정책 업데이트가 24시간 초과 시 OutOfDate 처리.
  4. 로그/감사
    • 이벤트 로그 → SIEM/EDR 전송 규칙 수립(원천: EventID 1000/1100/1200 + 체커 자체 로그).
    • 실패/예외(체커 미실행, 비정상 종료)는 별도 경보/티켓 자동 발행.
  5. 무결성/위장 방지
    • GUID/레지스트리 변경 탐지(Defender/EDR 커스텀 규칙, 파일/레지스트리 무결성 모니터링).
    • 업데이트 채널(배포 서버, CDN) 보안: TLS 고정, 서명 검증, 롤백 보호.
  6. 공식 통합 로드맵(권장)
    • POC 단계 이후에는 WSC API(예: IWscProduct 등) 를 호출하는 네이티브 서비스를 개발해
      • 상태(ON/OFF/Snoozed)
      • 서명/정책 최신 상태
      • 실행 경로(서명된 바이너리)를 COM/WMI 경로로 공식 보고하세요.
    • 이 경로는 OS 버전 호환성UI 반영이 가장 안정적입니다.

테스트 팁(시나리오 제안)

  • A시나리오: 체커 정상(ExitCode=0) → ProductState=0x10 & SignatureStatus=0 → 이벤트 로그 확인
  • B시나리오: 체커에서 위험 탐지(ExitCode=1) → ProductState=0x00 & SignatureStatus=1 → UI/로그 확인
  • C시나리오: 체커 일시중지/유지보수(ExitCode=2) → ProductState=0x20 & SignatureStatus=1 → 정책대로 알림

필요 시, checker.exe 대신 테스트용으로 cmd /c exit 1 같은 래퍼 배치 파일을 지정해 패턴 검증도 가능합니다.

확장(정식 통합을 위한 방향)

  • C/C++ 서비스 + WSC API 연동
    • 서비스에서 주기적으로 내부 점검 로직 실행 → 결과를 WSC API를 통해 보고
    • 예: IWscProduct::put_ProductState, put_SignatureStatus 등(네이티브/COM 기반)
  • COM 서버 등록/서명/설치패키지
    • MSI/Intune 패키징, 자동 업데이트, 롤백, 서명 검증 포함
  • 정책/규정/모니터링
    • “어떤 조건에서 경고/차단/권고로 볼 것인지”를 보안정책서로 배포
    • SIEM 상시 대시보드/알람 구성, EDR 탐지 룰 연동
728x90
그리드형(광고전용)

댓글