윈도우 보안 센터(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를 등록해야 합니다.
레지스트리 경로 예시
HKLM\SOFTWARE\Microsoft\Security Center\Provider\{GUID}
3. 보안 가이드
회사의 내부 보안 체커를 윈도우 보안 센터에 등록할 때 고려해야 할 점
- 권한 관리
- 로컬 SYSTEM 권한으로 동작해야만 보안 센터와 연동 가능.
- 잘못된 권한 설정 시 우회나 악성코드가 보안 제품을 가장할 위험 존재.
- 무결성 검증
- 자체 보안 체커 바이너리에 서명 코드(Code Signing)를 적용.
- Microsoft의 ELAM(Early Launch Anti-Malware) 구조 참고.
- 상태 보고 주기
- 일정 주기로 보안 상태(예: 취약점 점검 결과, 패치 적용 여부)를 보안 센터에 업데이트.
- 미보고 시 Windows 보안 센터에서 “보호되지 않음”으로 표시됨.
- 로그/감사
- 이벤트 로그(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
- 상태 변경 이벤트가 기록되는지 확인.
보안 점검 포인트
- 코드 서명: 내부 체커 실행 파일은 반드시 코드 서명(CA 인증서) 적용.
- 무결성 보호: 악성코드가 Provider로 위장하지 못하도록 CLSID/GUID 관리 필요.
- 업데이트 정책: 주기적으로 ProductState와 SignatureStatus 값 갱신.
- 중앙 모니터링: 이벤트 로그를 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/파일럿)
- 기능
- 공급자 GUID 생성 및 레지스트리 등록
- 내부 체커 실행 경로 등록
- 스케줄러(Task Scheduler)로 주기 실행 및 결과를
ProductState
/SignatureStatus
로 갱신 - 검증용 쿼리/로그 수집
- 제거(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
동작 확인(검증 시나리오)
- Windows 보안 UI
- Windows 보안 → 보호 영역(바이러스 및 위협 방지 등)에서 노출 여부 확인
- (주의) 레지스트리 POC만으로는 일부 버전에서 UI 반영이 제한될 수 있습니다.
- WMI 쿼리
- 보통
root/SecurityCenter2
네임스페이스의AntivirusProduct
등에서 조회됩니다. - POC 레지스트리만으로는 즉시 반영되지 않거나 표시되지 않을 수 있습니다.
- 확인 명령
Get-CimInstance -Namespace root/SecurityCenter2 -ClassName AntivirusProduct | Select-Object displayName,productState,pathToSignedProductExe
- 보통
- 이벤트 로그
- 이벤트 뷰어 → Windows Logs → Application
- Source=
MyCompanySecurityChecker
로 정보 이벤트(1000,1100,1200) 확인
- 스케줄러
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 "제거 완료"
실무 적용 포인트
- 코드 서명 필수
- 체커 실행 파일 및(정식 통합 시) COM/서비스 바이너리는 코드서명 하세요.
- 서명 무결성 검사를 배포 파이프라인/런타임에서 수행(서명자, 유효기간, 해시 등 검증).
- 권한 최소화
- 작업 스케줄러는 SYSTEM으로 돌려도 되지만, 체커 자체 작업은 최소권한 원칙 적용.
- 체커가 관리자 권한을 필요로 하는지, 왜 필요한지 문서화.
- 상태 기준 정의
- 종료코드 매핑(0=정상, 1=위험, 2=경고 등)과 “최신/구버전”의 정의를 명시.
- 예: 시그니처/정책 업데이트가 24시간 초과 시 OutOfDate 처리.
- 로그/감사
- 이벤트 로그 → SIEM/EDR 전송 규칙 수립(원천: EventID 1000/1100/1200 + 체커 자체 로그).
- 실패/예외(체커 미실행, 비정상 종료)는 별도 경보/티켓 자동 발행.
- 무결성/위장 방지
- GUID/레지스트리 변경 탐지(Defender/EDR 커스텀 규칙, 파일/레지스트리 무결성 모니터링).
- 업데이트 채널(배포 서버, CDN) 보안: TLS 고정, 서명 검증, 롤백 보호.
- 공식 통합 로드맵(권장)
- POC 단계 이후에는 WSC API(예:
IWscProduct
등) 를 호출하는 네이티브 서비스를 개발해- 상태(ON/OFF/Snoozed)
- 서명/정책 최신 상태
- 실행 경로(서명된 바이너리)를 COM/WMI 경로로 공식 보고하세요.
- 이 경로는 OS 버전 호환성과 UI 반영이 가장 안정적입니다.
- POC 단계 이후에는 WSC API(예:
테스트 팁(시나리오 제안)
- 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 탐지 룰 연동
댓글