부분적으로 제거된 .NET 설치는 Microsoft Defender 취약성 관리 같은 취약성 검사 소프트웨어가 디바이스를 보고하는 일반적인 이유입니다. .NET 설치가 작동하는 방식을 이해하면 관리자가 보고서를 조사하고 수정 작업을 수행하는 데 도움이 될 수 있습니다.
Windows 런타임 및 SDK와 같은 .NET 구성 요소는 여러 MSI로 구성됩니다. 개별 MSI는 직접 배포되지 않습니다. 대신 번들을 만들기 위해 함께 연결됩니다.
Windows .NET 획득
- 독립 실행형 번들(EXE)은 .NET 웹 사이트에서 다운로드할 수 있습니다.
- WinGet은 .NET 번들을 포함하는 패키지를 제공합니다.
- 서비스 업데이트는 자동 업데이트, WSUS 및 Windows 업데이트 카탈로그를 사용하여 Microsoft 업데이트를 통해 번들을 배포합니다.
- ISV(독립 소프트웨어 공급업체)는 .NET 번들을 소프트웨어의 일부로 재배포할 수 있습니다.
- OEM은 때때로 새 디바이스의 팩터리 이미지에 .NET 번들의 미리 설치된 복사본을 포함합니다.
- Windows 일부 Azure 마켓플레이스 이미지에는 번들의 미리 설치된 복사본이 포함됩니다.
- Chocolatey와 같은 타사 패키지 관리자도 .NET 번들을 배포합니다.
- 기업에서는 내부 배포를 위해 독점 패키지를 사용하여 번들을 재포장하는 경우가 있습니다.
- 일부 .NET 애플리케이션 호스트는 사용자에게 누락된 런타임 번들을 다운로드하고 설치하도록 지시할 수도 있습니다.
Visual Studio 사용하여 .NET 획득하고 독립 실행형 번들로 동일한 MSI를 사용할 수도 있습니다.
메모
.NET SDK 번들은 16.2까지 Visual Studio 함께 제공됩니다. Visual Studio 16.3의 .NET Core 3.0부터 SDK 번들은 개별 .NET MSI로 대체되었습니다.
Upgrades
.NET 주/부 릴리스 내의 패치 버전 간 업그레이드를 지원합니다. .NET 8.0.7은 시험판 버전을 포함하여 8.0.4 또는 8.0.0과 같은 이전 릴리스를 업그레이드하지만 .NET 7.0과 같은 이전 주 릴리스는 업그레이드하지 않습니다. .NET SDK는 기능 대역 내의 패치 간 업그레이드를 지원합니다. 8.0.100 SDK는 8.0.103으로 업그레이드할 수 있지만 8.0.3xx SDK는 1xx 또는 2xx 기능 밴드를 업그레이드하지 않습니다.
대부분의 업그레이드는 번들 수준에서 처리됩니다. 이전 버전은 새 버전이 설치된 후에만 제거됩니다. 두 가지 예외가 있습니다. .NET 호스트 및 ASP.NET Core 모듈 MSI가 현재 위치에서 업데이트됩니다.
.NET 8부터 사용자는 이전 버전의 번들을 제거하는 것을 연기할 수 있습니다.
번들 컴퍼지션 및 참조 계산
번들은 여러 MSI로 구성되며, 그 중 일부는 여러 번들 간에 공유됩니다.
- 런타임 번들에는 데스크톱 런타임 및 SDK 번들에도 제공되는 3개의 MSI가 포함되어 있습니다.
- 데스크톱 번들에는 SDK 번들과 공유되는 추가 MSI가 포함되어 있습니다.
- SDK에는 .NET 애플리케이션을 만들고 빌드하는 데 사용되는 CLI, 템플릿 및 대상 지정 팩이 포함된 추가 MSI가 포함되어 있습니다.
공유 MSI는 참조 계산을 사용하여 관리됩니다. 모든 .NET MSI는 번들이 자신을 종속으로 등록할 수 있도록 하는 공급자 키라는 레지스트리 키를 만듭니다. MSI가 이미 설치된 경우 번들은 등록 정보만 업데이트합니다. 번들은 제거되면 등록 취소됩니다. 공유 MSI는 등록된 종속 항목이 없는 경우에만 제거됩니다.
아래 레지스트리 정보는 .NET 호스트 MSI 공급자 키의 예입니다. Visual Studio 포함하여 4개의 등록된 종속이 있습니다.
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Installer\Dependencies\Dotnet_CLI_SharedHost_10.0_x64
(Default) REG_SZ {8A8CC49F-7D1E-45DC-B7B5-35FF61A2C25E}
Version REG_SZ 80.40.55332
DisplayName REG_SZ Microsoft .NET Host - 10.0.10 (x64)
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Installer\Dependencies\Dotnet_CLI_SharedHost_10.0_x64\Dependents\VS.{AEF703B8-D2CC-4343-915C-F54A30B90937}
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Installer\Dependencies\Dotnet_CLI_SharedHost_10.0_x64\Dependents\{609A456D-467D-4077-9BA2-B6404F1B1163}
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Installer\Dependencies\Dotnet_CLI_SharedHost_10.0_x64\Dependents\{866BECDA-F284-473A-9E84-0CCE816BF06F}
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Installer\Dependencies\Dotnet_CLI_SharedHost_10.0_x64\Dependents\{FD5EA214-C690-466F-B8FB-1741881913F9}
메모
예를 들어 제거가 중단되는 경우 번들이 제거된 후 종속 데이터베이스가 등록된 상태로 유지되면 개별 MSI가 분리됩니다.
메모
Visual Studio 잘 알려진 값을 VS.{AEF703B8-D2CC-4343-915C-F54A30B90937}사용하여 자신을 종속 값으로 등록합니다. 실제 참조 수는 각 Visual Studio 인스턴스에 대한 설치 매니페스트를 확인하여 결정됩니다.
배포된 빈 설치
배포된 Bin 설치는 MSI와 연결되지 않은 .NET 복사본을 참조합니다. 이 작업은 설치 스크립트를 관리자로 실행하고 설치 디렉터리를 'Program Files\dotnet'으로 설정하여 수행할 수 있습니다. Bin 배포 설치는 수정을 복잡하게 만들 수 있습니다. 스캐너는 취약성을 보고하지만 관리자는 제거할 MSI를 찾을 수 없습니다. DNIM은 배포된 bin 설치를 검색할 수 있습니다.
탐지
DNIM은 여러 가지 추론을 사용하여 .NET 연결된 번들 및 MSI를 식별합니다. 비고의 디바이스를 성공적으로 수정하려면 설치를 정확하게 검색하는 것이 중요합니다.
번들
번들은 레지스트리에 저장된 표시 이름 및 파일 정보를 사용하여 식별됩니다. 실행 파일에서 유효한 설치 관리자인지 확인하기 위해 추가 검사가 수행됩니다. 또한 이 informatio는 각 릴리스에 대해 게시되는 JSON 데이터 .NET 비교됩니다.
MSI 검색
DNIM은 레지스터 아래에 HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components 저장된 설치 관리자 구성 요소 데이터에 대해 철저한 검색을 수행하여 .NET MSI를 식별합니다.
각 하위 키는 다른 구성 요소 ID를 나타냅니다. 각 키 아래의 값은 제품 코드를 나타냅니다. 구성 요소 ID와 제품 코드는 모두 압축된 GUID로 저장됩니다. 아래 예제는 .와 연결된 구성 요소의 예제입니다 dotnet.exe.
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\BBB993545ADD68342A9E16F83B5CA481
40A3E8A8CB38EDC4299598B366C6A11B REG_SZ C:\Program Files\dotnet\dotnet.exe
A75437C333A10ED46B2CF6AB78E7F1FC REG_SZ C:\Program Files (x86)\dotnet\dotnet.exe
79D2396D1F638B04C9CDAC38562B0100 REG_SZ C:\Program Files\dotnet\dotnet.exe
EA6D9CBF69367CF4CB81005882631FD6 REG_SZ C:\Program Files (x86)\dotnet\dotnet.exe
872D9C61B8AA60F47A4CDF137C8523A3 REG_SZ C:\Program Files (x86)\dotnet\dotnet.exe
6235DF10DB18AED4F910D396BBDD7AE5 REG_SZ C:\Program Files\dotnet\dotnet.exe
0370151E43A53FE48B564853D1B81FAB REG_SZ C:\Program Files\dotnet\dotnet.exe
F6D22817F79056B46B45655C7495EE9A REG_SZ C:\Program Files (x86)\dotnet\dotnet.exe
D512842CB6C6A404BAE605D564042E50 REG_SZ C:\Program Files\dotnet\dotnet.exe
Bin 배포된 설치
DNIM은 설치 관리자 구성 요소에 대한 철저한 검색을 수행하므로 MSI와 연결되지 않은 파일 Program Files\dotnet 은 bin 배포 설치로 분류됩니다.
Classification
잘못된 설치 분류로 인해 잘못된 설치가 제거되거나 유지되어 애플리케이션이 손상되거나 디바이스가 비준수 상태로 남을 수 있습니다.
제품(예: NET 10)이 식별되면 릴리스(예: 10.0.4) 및 지원 단계(예: 활성)와 같은 추가 정보를 확인할 수 있습니다. 이렇게 하면 관리자가 유연한 배포를 만들 수 있습니다.
설치는 .NET 구성 요소(ASP.NET Core, SDK 등), 아키텍처 및 설치 유형(번들, MSI 또는 bin 배포됨)에 따라 추가로 분류됩니다.
언급할 만한 몇 가지 특별한 경우가 있습니다.
.NET Standard 2.1
일관된 동작을 보장하려면 제품, 릴리스 및 지원 단계를 정의하기 위해 설치가 필요합니다. .NET Standard 2.1의 대상 지정 팩은 흥미로운 과제를 제시합니다. 실행 코드는 포함되지 않으며 표준에서 정의한 API에 대한 참조 어셈블리만 제공합니다. 대상 팩은 먼저 .NET Core 3.0.100 SDK의 일부로 제공되었지만 .NET 10까지 모든 후속 SDK에 포함되었습니다. DNIM은 .NET Core 3.0에서 릴리스 및 제품을 분류하지만 지원 단계는 활성 지원 중인 SDK에 포함될 수 있으므로 항상 활성으로 보고됩니다.
메모
.NET Standard 2.1 대상 지정 팩은 .NET 10의 SDK 설치에서 제거되었습니다. SDK는 애플리케이션을 빌드할 때 NuGet 패키지를 사용하여 누락된 대상 지정 팩을 자동으로 다운로드합니다.
SDK 기능 밴드 .NET
.NET Core 1.0 및 1.1에서 SDK는 runime와 유사한 버전 관리 체계를 사용했습니다. .NET Core 1.1의 마지막 SDK는 1.1.14로 버전이 지정되었으며 1.1.13 런타임이 포함되었습니다.
SDK 기능 밴드는 Visual Studio 지원되는 기능을 구분하기 위해 2.1.100 SDK에 도입되었습니다. SDK는 .NET Core 2.0.5 릴리스의 일부로 제공되었습니다. 마지막 2.0 SDK는 2.1.202로 버전이 지정되었으며 2.0.9 릴리스에 포함되었습니다. .NET Core 2.1에서 제공되는 첫 번째 SDK는 2.1.300으로 버전이 지정되었습니다. 이후 릴리스에서 SDK 기능 밴드는 항상 100부터 시작합니다(예: 2.2.100, 3.0.100 등).
.NET