Windows 무결성 메커니즘 디자인
Windows 무결성 메커니즘은 커널의 보안 참조 모니터를 기반으로 하는 Windows 보안 아키텍처의 확장입니다. 보안 참조 모니터는 보안 액세스 토큰의 사용자 및 그룹 SID를 개체 보안 설명자의 ACL에 부여된 액세스 권한과 비교하여 액세스 제어를 적용합니다. 무결성 메커니즘은 보안 액세스 토큰에 무결성 수준을 추가하고 보안 설명자의 시스템 ACL(SACL)에 필수 레이블 액세스 제어 항목을 추가합니다.
무결성 메커니즘의 주요 부분은 다음과 같습니다.
- 미리 정의된 무결성 수준 및 해당 표현입니다.
- 액세스 권한을 제한하는 무결성 정책.
- 보안 액세스 토큰에 할당된 무결성 수준입니다.
- 필수 레이블 액세스 제어 항목입니다.
- 개체에 할당된 필수 레이블입니다.
- AccessCheck 및 커널 모드 SeAccessCheck API 내의 무결성 제한.
이러한 각 부분은 아래에 자세히 설명되어 있습니다. Windows 무결성 메커니즘은 다른 보안 정책 옵션과 관계없이 항상 적용됩니다. 액세스 제어 검사와 같은 무결성 수준 검사는 선택 사항이 아닙니다. 무결성 수준 검사를 사용하지 않도록 설정하는 보안 정책 옵션은 없습니다. 무결성 메커니즘은 UAC를 지원하지만 보안 그룹 정책 UAC를 사용하지 않도록 설정하면 무결성 메커니즘이 계속 적용됩니다.
무결성 수준
Windows는 SID를 사용하여 무결성 수준을 정의합니다. SID를 사용하여 무결성 수준을 나타내면 코드를 변경하지 않고도 무결성 메커니즘을 기존 보안 데이터 구조에 쉽게 통합할 수 있습니다. 무결성 수준 SID의 형식은 S-1-16-xxxx입니다. 표 1은 무결성 수준 SID의 구성 요소를 보여 줍니다.
표 1 무결성 수준 SID 식별자 권한 값
값 | Description |
---|---|
16 |
필수 레이블 기관(SECURITY_MANDATORY_LABEL_AUTHORITY)을 나타냅니다. |
xxxx |
무결성 수준인 RID(상대 식별자) 필드를 나타냅니다. RID는 무결성 수준을 나타내는 16진수 값입니다. |
Windows Vista에는 4개의 해당 값이 있는 네 가지 기본 무결성 수준이 있습니다. 값이 낮을 경우 무결성 수준이 낮거나 신뢰도가 낮음을 나타냅니다. 이러한 값은 헤더 파일 winnt.h에 정의됩니다. 표 2에는 정의된 무결성 수준과 해당 값이 나와 있습니다.
표 2 정의된 무결성 수준 및 해당 값
값 | 설명 | 기호 |
---|---|---|
0x0000 |
신뢰할 수 없는 수준 |
SECURITY_MANDATORY_UNTRUSTED_RID |
0x1000 |
낮은 무결성 수준 |
SECURITY_MANDATORY_LOW_RID |
0x2000 |
중간 무결성 수준 |
SECURITY_MANDATORY_MEDIUM_RID |
0x3000 |
높은 무결성 수준 |
SECURITY_MANDATORY_HIGH_RID |
0x4000 |
시스템 무결성 수준 |
SECURITY_MANDATORY_SYSTEM_RID |
중간 무결성 수준 SID의 예는 S-1-16-8192 문자열입니다. RID 값 8192는 0x2000 10진수에 해당합니다.
RID는 나중에 추가 수준을 정의할 수 있도록 0x1000 간격으로 구분됩니다. 또한 분리를 사용하면 특정 시스템 디자인 목표를 충족하기 위해 보통보다 약간 높은 프로세스에 무결성 수준을 할당할 수 있습니다.
정의된 무결성 수준 SID에는 문자열 이름 값이 연결되어 있습니다. API LookupAccountSID 를 사용하면 각 무결성 수준 SID에 대한 문자열 이름이 반환됩니다. 표 3에는 무결성 수준에 대한 문자열 이름이 표시됩니다.
표 3 무결성 수준 문자열 이름
무결성 수준 SID | 속성 |
---|---|
S-1-16-4096 |
필수 레이블\낮은 필수 수준 |
S-1-16-8192 |
필수 레이블\중간 필수 수준 |
S-1-16-12288 |
필수 레이블\높은 필수 수준 |
S-1-16-16384 |
필수 레이블\시스템 필수 수준 |
무결성 수준은 SDDL(보안 설명자 정의 언어)에서 SID 문자열로도 정의됩니다. SDDL은 ConvertSecurityDescriptorToStringSecurityDescriptor 및 ConvertStringSecurityDescriptorToSecurityDescriptor 함수가 보안 설명자를 텍스트 문자열로 설명하는 데 사용하는 문자열 형식을 정의합니다. 또한 언어는 보안 설명자의 구성 요소에서 정보를 설명하는 문자열 요소를 정의합니다. SDDL을 사용하여 무결성 수준을 정의하면 개체를 만들 때 개체의 무결성 수준을 편리하게 정의할 수 있습니다. 무결성 수준에 대한 SID 문자열에 대한 자세한 내용은 Windows 무결성 메커니즘 리소스를 참조하세요. 필수 레이블에 대한 SDDL 지원은 부록 A: 필수 레이블에 대한 SDDL에 설명되어 있습니다.
Windows Vista는 보안 액세스 토큰의 무결성 수준 SID를 사용하여 주체 무결성 수준을 나타내고 보안 설명자의 필수 레이블 ACE에서 무결성 수준 SID를 사용하여 개체 무결성 수준을 나타냅니다.
무결성 정책
Windows 무결성 메커니즘은 간단한 정책을 사용하여 개체의 필수 레이블을 사용하여 낮은 무결성 주체에 사용할 수 있는 액세스 수준을 제한하는 방법을 결정합니다. 즉, 정책은 낮은 무결성 수준 개체가 더 높은 무결성 수준 개체에 대해 가질 수 있는 액세스 유형을 제한합니다. 표 4에는 두 가지 정책 범주가 표시됩니다.
표 4 무결성 정책 범주
범주 | Description |
---|---|
액세스 토큰 필수 정책 |
액세스 토큰에서 를 설정하고 액세스 토큰에 표시되는 주체에 필수 정책이 적용되는 방식을 결정합니다. |
필수 레이블 정책 |
개체에 대한 필수 레이블 ACE(아래 설명)에서 를 설정하고 개체에 대한 액세스를 제한하는 방법을 결정합니다. |
무결성 정책은 보안 개체에 대한 액세스 권한을 평가할 때 필수 정책 검사 수행될 때 사용됩니다. 정책은 무결성 수준에서 액세스 권한을 제한하는 방법을 결정합니다.
필수 액세스 토큰 정책
표 5에는 Windows Vista에 정의된 필수 액세스 토큰 정책이 표시됩니다.
표 5 Windows Vista의 필수 액세스 토큰 정책
정책 | 설명 |
---|---|
TOKEN_MANDATORY_NO_WRITE_UP |
모든 액세스 토큰에 할당된 기본 정책입니다. 정책은 이 주체의 쓰기 액세스를 더 높은 무결성 수준의 개체로 제한합니다. |
TOKEN_MANDATORY_NEW_PROCESS_MIN |
자식 프로세스에 무결성 수준을 할당하는 동작을 제어합니다. 일반적으로 자식 프로세스는 부모 프로세스 액세스 토큰이 자식에 할당된 경우 부모 프로세스의 무결성 수준을 상속합니다. NEW_PROCESS_MIN 정책을 사용하면 자식 프로세스의 무결성 수준이 부모 액세스 토큰의 최소 무결성 수준 또는 새 프로세스에 대한 실행 파일의 개체 무결성 수준이 됩니다. 이 정책은 모든 액세스 토큰에서 기본적으로 설정됩니다. |
NEW_PROCESS_MIN 정책은 예제에서 설명할 수 있습니다. lowcalc.exe 라는 실행 프로그램이 있다고 가정합니다. 프로그램 파일에 낮은 무결성 레이블이 할당됩니다. 명령 프롬프트에서 사용자는 lowcalc.exe 실행합니다. 부모 프로세스(cmd.exe)가 중간 무결성 수준에서 실행되고 있습니다. lowcalc.exe 이미지 파일에는 낮은 무결성 레이블이 있으므로 NEW_PROCESS_MIN 정책은 새 프로세스의 무결성 수준(lowcalc)을 낮음으로 설정합니다. 아래 예제에서는 낮은 무결성 수준에서 실행할 애플리케이션 디자인 섹션에 나와 있습니다.
필수 레이블 정책
필수 레이블 정책은 필수 레이블 액세스 제어 항목의 마스크 필드에 플래그(비트)로 정의됩니다. 이러한 정책 플래그는 낮은 무결성 주체에 적용되는 액세스 권한에 대한 제한을 결정합니다. 표 6에는 Windows Vista에 정의된 필수 레이블 정책이 표시됩니다.
Windows Vista의 표 6 필수 레이블 정책
정책 | 설명 |
---|---|
SYSTEM_MANDATORY_POLICY_NO_WRITE_UP |
모든 개체 필수 레이블에 대한 기본 정책입니다. 플래그는 NO_WRITE_UP 액세스 토큰 정책과 동일합니다. 이 정책은 무결성 수준이 낮은 주체에 의해 개체에 대한 쓰기 액세스를 제한합니다. |
SYSTEM_MANDATORY_POLICY_NO_READ_UP |
무결성 수준이 낮은 주체에 의해 개체에 대한 읽기 액세스를 제한합니다. 예를 들어 정책은 프로세스의 가상 메모리 주소 공간에 대한 읽기 액세스를 제한하는 데 사용됩니다. |
SYSTEM_MANDATORY_POLICY_NO_EXECUTE_UP |
무결성 수준이 낮은 주체에 의해 개체에 대한 실행 액세스를 제한합니다. 예를 들어 이 정책은 낮은 무결성 주체에 의해 COM 클래스에 대한 시작 활성화 권한을 제한하는 데 사용됩니다. |
이러한 정의된 정책은 Windows Vista의 디자인 목표를 충족합니다. 무결성 메커니즘의 아키텍처는 다양한 무결성 수준에서 주체와 개체 간의 액세스 권한을 제어하는 추가 정책 옵션을 정의하여 향후 확장을 허용합니다.
무결성 정책이 일반 권한에 매핑되는 방법
필수 정책 검사 AccessCheck 보안 함수의 일부로 발생합니다. AccessCheck(및 커널 모드의 SeAccessCheck)에는 GENERIC_MAPPING 구조체의 함수 매개 변수 중 하나가 있습니다. 호출자가 제공하는 제네릭 매핑은 개체별 액세스 권한을 읽기, 쓰기 및 실행의 제네릭 범주에 매핑합니다. 필수 레이블 정책은 제네릭 범주에 따라 허용되는 액세스에 대한 제한을 구현합니다. 특정 개체 형식의 경우 GENERIC_MAPPING 특정 액세스 권한이 금지된 검사 필수 정책과 통신합니다.
AccessCheck 호출에 전달되는 GENERIC_MAPPING 구조체가 모두 0이면 제네릭 매핑이 정의되지 않습니다. 일반 매핑이 정의되지 않은 경우 필수 정책 검사 모든 액세스 권한을 낮은 무결성 주체별로 제한합니다. 프라이빗 개체 보안에 AccessCheck를 사용하고 모든 0의 GENERIC_MAPPING 구조를 전달하는 리소스 관리자에게 액세스 거부 오류가 표시됩니다. 필수 정책이 적용하는 일반 액세스 권한에 개체 유형별 액세스 권한을 매핑하려면 리소스 관리자 애플리케이션에 대한 코드 변경이 필요합니다.
액세스 토큰에 무결성 수준을 할당하는 방법
보안 액세스 토큰은 커널에서 사용하는 내부 데이터 구조입니다. 보안 액세스 토큰에는 권한, 그룹 멤버 자격 및 기타 보안 관련 세부 정보에 해당하는 다양한 정보 값이 포함되어 있습니다. 액세스 토큰 초기화는 사용자가 Windows에 대화형으로 로그온하거나 네트워크 인증이 발생할 때 발생합니다. 액세스 토큰이 초기화되면 다른 값 외에도 사용자의 SID, 그룹 SID 및 권한이 추가됩니다. Windows Vista는 액세스 토큰이 초기화될 때 액세스 토큰에 대한 무결성 수준을 할당합니다.
커널은 모든 프로세스 및 스레드에 액세스 토큰을 할당합니다. 프로세스의 기본 액세스 토큰에는 해당 프로세스와 연결된 무결성 수준이 포함됩니다. Windows 무결성 메커니즘에서 프로세스의 무결성 수준을 주체 무결성 수준이라고 합니다. 애플리케이션의 액세스 토큰에 중간 무결성 SID가 포함된 경우 애플리케이션 프로세스가 중간 무결성 수준에서 실행됩니다. 동일한 사용자 계정에서 실행되는 여러 애플리케이션 프로세스에는 동일한 기본 액세스 토큰이 할당됩니다. 각 애플리케이션에 동일한 무결성 수준이 할당되는 방식입니다.
무결성 수준은 TOKEN_GROUPS 구조에 있는 특정 그룹 SID에 따라 액세스 토큰에 할당됩니다. Windows 커널은 특정 기본 제공 사용자 또는 그룹 계정을 기반으로 무결성 수준을 할당합니다. Windows Vista는 로컬 시스템 계정 SID가 시스템의 무결성 수준을 제공하는 액세스 토큰을 할당하고, 로컬 Administrators 그룹 SID가 있는 액세스 토큰에 높은 무결성 수준이 할당되고, 표준 사용자 계정에 대한 액세스 토큰에 중간의 무결성 수준이 할당됩니다.
표 7은 특정 SID의 존재에 따라 액세스 토큰에 대한 무결성 수준의 할당을 보여 줍니다.
표 7 특정 SID에 연결된 무결성 수준
액세스 토큰의 SID | 할당된 무결성 수준 |
---|---|
LocalSystem |
시스템 |
LocalService |
시스템 |
NetworkService |
시스템 |
관리자 |
높음 |
Backup Operators |
높음 |
Network Configuration Operators |
높음 |
Cryptographic Operators |
높음 |
인증된 사용자 |
중간 |
모든 사람(세계) |
낮음 |
익명 |
신뢰할 수 없는 |
무결성 수준은 다양한 수준의 액세스에서 실행되는 애플리케이션에 대해 서로 다른 수준의 신뢰도를 정의합니다. Windows Vista의 대부분의 애플리케이션은 중간 무결성 수준에서 표준 사용자 액세스 수준에서 실행됩니다. 중간 무결성 수준의 애플리케이션은 중간 무결성 수준에서 다른 애플리케이션 및 데이터와 상호 작용하는 방법에 대한 제한을 경험하지 않습니다. 관리 권한이 필요한 특정 작업 또는 애플리케이션은 높은 무결성 수준에서 실행됩니다. 시스템 서비스는 기본 데스크톱과 상호 작용하는 기능에 제한이 있고 강력한 시스템 권한으로 실행되는 경우가 많기 때문에 시스템 무결성 수준에서 실행됩니다. 보호 모드 인터넷 Explorer 같이 가능한 가장 적은 권한으로 실행되도록 설계된 몇 가지 애플리케이션은 낮은 무결성 수준으로 실행할 수 있습니다.
특정 관리 Windows 권한은 적어도 높은 무결성 수준의 액세스 토큰에만 할당할 수 있습니다. 액세스 토큰 무결성 수준이 높지 않으면 특정 관리 권한이 허용되지 않으며 액세스 토큰에서 제거됩니다. 높은 무결성 수준과 연결된 관리 권한은 다음과 같습니다.
- SE_CREATE_TOKEN_PRIVILEGE
- SE_TCB_PRIVILEGE
- SE_TAKE_OWNERSHIP_PRIVILEGE
- SE_BACKUP_PRIVILEGE
- SE_RESTORE_PRIVILEGE
- SE_DEBUG_PRIVILEGE
- SE_IMPERSONATE_PRIVILEGE
- SE_RELABEL_PRIVILEGE
- SE_LOAD_DRIVER_PRIVILEGE
애플리케이션은 자식 프로세스를 만들 때 중복 액세스 토큰에 낮은 무결성 수준을 할당할 수 있습니다. 실행 파일 프로그램 이미지 파일에 낮은 필수 레이블이 있는 경우 Windows에서 낮은 무결성 수준으로 애플리케이션 프로세스를 실행할 수 있습니다. 이러한 기능은 이 문서의 뒷부분에 설명되어 있습니다.
액세스 토큰에 대한 무결성 수준을 가져오는 방법
무결성 수준은 TOKEN_GROUPS 필드를 사용하여 액세스 토큰에 저장됩니다. TOKEN_GROUPS 구조는 해당 사용자 계정에 대한 그룹 멤버 자격을 식별하는 SID 및 특성 목록입니다. 액세스 토큰 무결성 수준은 SID 특성을 사용하여 그룹 목록에서도 식별됩니다. SID_AND_ATTRIBUTES 구조에는 무결성 수준 SID가 포함되며 무결성 수준은 SE_GROUP_INTEGRITY 및 SE_GROUP_INTEGRITY_ENABLED 특성을 사용하여 식별됩니다.
GetTokenInformation API를 사용하여 액세스 토큰에서 액세스 토큰 무결성 수준을 검색할 수 있습니다. GetTokenInformation에는 검색할 액세스 토큰 정보 클래스를 나타내는 매개 변수가 있습니다. TOKEN_INFORMATION_CLASS 매개 변수에는 무결성 수준 TokenIntegrityLevel에 대해 정의된 값이 있습니다. 반환되는 데이터 구조는 TOKEN_MANDATORY_LABEL 형식입니다.
프로세스의 무결성 수준을 확인하려면
프로세스의 액세스 토큰에 대한 핸들을 엽니다.
액세스 토큰의 무결성 수준을 가져옵니다.
무결성 수준 SID를 시스템 정의 무결성 수준 RID와 비교합니다.
액세스 토큰 무결성 수준을 가져오기 위한 예제 코드는 부록 D에 표시됩니다.
액세스 토큰의 무결성 수준을 보는 방법
프로세스의 보안 액세스 토큰의 무결성 수준은 프로세스의 보안 세부 정보를 노출하는 도구(예: SysInternals.com 프로세스 Explorer)를 사용하여 볼 수 있습니다. 다음 이미지는 보기(오른쪽)에 무결성 수준 열이 추가된 프로세스 Explorer 표시를 보여 줍니다.
그림 1 프로세스 Explorer 무결성 수준
explorer.exe 같은 특정 프로세스의 보안 속성을 살펴보면 프로세스 Explorer 프로세스의 보안 액세스 토큰에 정의된 그룹 목록에 무결성 수준이 표시됩니다. 다음 이미지는 프로세스에 대한 액세스 토큰에 할당된 필수 레이블/중간 필수 수준을 보여 explorer.exe.
그림 2는 중간 무결성 수준 프로세스로 Explorer.exe.
액세스 토큰의 무결성 수준을 설정하는 방법
애플리케이션은 일반적으로 프로세스의 무결성 수준 값을 변경할 필요가 없습니다. 애플리케이션은 일반적으로 보안 액세스 토큰의 값을 변경할 필요가 없습니다. 그러나 경우에 따라 다른 무결성 수준에서 로컬 클라이언트를 지원하는 서비스는 낮은 무결성 수준에서 작업을 수행하도록 선택할 수 있습니다. 가장은 서비스 스레드가 낮은 무결성 수준에서 실행될 수 있는 한 가지 방법입니다. 서비스 스레드가 로컬 클라이언트를 가장하는 경우 가장 스레드에는 클라이언트가 동일한 로컬 컴퓨터에서 실행되는 경우 클라이언트의 무결성 수준을 포함하는 클라이언트의 보안 컨텍스트가 있습니다.
애플리케이션이 낮은 무결성 수준에서 파일 및 레지스트리 키 집합을 만드는 것과 같은 작업을 수행할 수 있는 또 다른 방법은 현재 스레드 액세스 토큰에 대한 TokenIntegrityLevel을 설정하는 것입니다. 새 무결성 수준은 프로세스의 기본 액세스 토큰에서 무결성 수준보다 높을 수 없습니다.
스레드에서 액세스 토큰 무결성 수준의 값을 설정하려면
OpenThreadToken을 호출하여 액세스 토큰에 대한 핸들을 가져옵니다.
TokenIntegrityLevel의 TOKEN_INFORMATION_CLASS 매개 변수 값으로 GetTokenInformation을 호출하여 현재 스레드 무결성 수준을 저장합니다.
TokenIntegrityLevel의 TOKEN_INFORMATION_CLASS 매개 변수 값을 사용하여 SetTokenInformation을 호출합니다.
서로 다른 무결성 수준의 스레드 간에 프로세스 주소 공간 내에 보안 경계가 없으므로 애플리케이션 디자이너는 더 높은 무결성 프로세스에서 실행되는 낮은 무결성에서 스레드에서 코드를 실행하는 잠재적 보안 위험을 고려해야 합니다. 대부분의 애플리케이션은 낮은 무결성 수준에서 실행되는 별도의 프로세스를 만들어 낮은 무결성 작업을 수행하는 것이 더 간단할 수 있습니다.
TokenIntegrityLevel을 설정하고 더 낮은 무결성 수준에서 프로세스를 만드는 방법의 예는 액세스 토큰의 무결성 수준을 설정하는 방법에 나와 있습니다.
필수 레이블 ACE
Windows 무결성 메커니즘은 시스템 필수 레이블 ACE인 새 ACE 형식을 정의합니다. 필수 레이블 ACE는 개체의 보안 설명자에 있는 개체의 필수 레이블을 나타내는 데 사용됩니다. 필수 레이블에는 무결성 수준 및 관련 무결성 정책이 포함됩니다. 필수 레이블 ACE는 보안 설명자의 시스템 ACL 또는 SACL에서만 사용됩니다. SACL은 DACL(임의 ACL)과 보안 설명자의 별도 필드입니다.
그림 3 보안 설명자 필드
임의 ACL에는 개체에 대한 사용자 및 그룹 액세스 권한이 포함됩니다. 모든 사용자 또는 그룹은 WRITE_DAC 개체 액세스 권한을 사용하여 DACL을 업데이트할 수 있습니다. 임의 ACL은 다른 사용자가 더 자주 업데이트할 수 있습니다. 무결성 메커니즘의 디자인 목표 중 하나는 필수 레이블이 개체에 적용된 후 보안 시스템이 개체를 사용하여 레이블을 유지 관리해야 한다는 것입니다. ACL을 관리하도록 설계된 애플리케이션에 거의 또는 전혀 영향을 주지 않고 개체 보안 설명자에 적절한 필수 레이블을 적용하는 작업은 주로 보안 시스템의 제어 하에 있는 시스템 ACL에 필수 레이블을 배치하여 수행됩니다. 필수 레이블은 SACL의 시스템 감사 항목과 논리적으로 분리됩니다. 필수 레이블이 SACL의 시스템 감사 항목 앞에 오거나 따르는 데 필요한 순서는 없습니다.
필수 레이블 ACE는 ACE 헤더, 액세스 마스크 및 SID를 포함하는 액세스 허용 ACE와 유사합니다. 필수 레이블 ACE의 SID 부분에는 무결성 수준 SID가 포함됩니다. 표 8에는 ACE 헤더의 필드가 표시됩니다.
테이블 8 ACE 헤더에 포함된 필드
ACE 헤더 필드 | 값 |
---|---|
AceType |
SYSTEM_MANDATORY_LABEL_ACE_TYPE |
AceFlags |
필수 레이블 ACE 형식의 상속을 정의하는 컨트롤 플래그 |
AceSize |
필수 레이블 ACE의 크기 |
필수 레이블 ACE에는 마스크 필드가 포함되어 있습니다. 마스크는 낮은 무결성 수준의 프로세스(또는 주체)에 적용되는 액세스 권한에 대한 제한을 결정하는 필수 정책을 정의하는 데 사용됩니다. Windows Vista에서 널리 사용되는 예제 정책은 NO_WRITE_UP 정책입니다. 필수 레이블 ACE 마스크의 NO_WRITE_UP 정책 플래그는 개체의 필수 레이블에 있는 무결성 수준 SID보다 무결성 수준이 낮은 주체가 개체에 대한 일반 쓰기 액세스를 가져오지 못하도록 제한됨을 의미합니다.
개체에는 유효한 필수 레이블이 하나만 있습니다. 보안 설명자가 SACL에서 둘 이상의 필수 레이블을 가져오는 경우 SACL의 첫 번째 필수 레이블 ACE는 개체의 유효 레이블입니다.
필수 레이블 ACE에 대한 자세한 내용은 Windows 무결성 메커니즘 리소스를 참조하세요.
필수 레이블 ACE 읽기
Windows Vista는 보안 함수 GetSecurityInfo를 사용하여 개체에서 필수 레이블 정보를 읽습니다. GetSecurityInfo는 개체에서 소유자, 그룹, DACL 또는 SACL 정보를 가져옵니다. GetSecurityInfo에 대한 SECURITY_INFORMATION 매개 변수는 반환되는 보안 설명자의 일부를 결정합니다. Windows Vista는 SACL에서 필수 레이블 ACE를 반환하는 데 사용되는 새 보안 정보 값인 LABEL_SECURITY_INFORMATION 정의합니다. GetSecurityInfo 호출이 SACL_SECURITY_INFORMATION 지정하는 경우 SACL의 시스템 감사 API만 반환되고 필수 레이블 ACE는 반환되지 않습니다.
개체에 대한 필수 레이블 ACE를 읽는 데 필요한 액세스 권한은 READ_CONTROL 표준 액세스 권한입니다. 일반적으로 SACL에서 정보를 얻거나 설정하려면 ACCESS_SYSTEM_SECURITY 액세스 권한이 필요합니다. ACCESS_SYSTEM_SECURITY 액세스 토큰에서 SE_SECURITY_NAME 권한이 활성화된 경우에만 부여됩니다. SACL에서 필수 레이블을 읽으면 SE_SECURITY_NAME 권한 또는 ACCESS_SYSTEM_SECURITY 액세스 권한이 필요하지 않습니다.
필수 레이블 ACE 설정
Windows Vista는 보안 함수인 SetSecurityInfo를 사용하여 개체의 필수 레이블 정보를 변경합니다. 개체의 필수 레이블은 개체를 만들 때 보안 하위 시스템에 의해 설정됩니다. SetSecurityInfo에 대한 SECURITY_INFORMATION 매개 변수에는 보안 설명자의 필수 레이블을 변경하려면 LABEL_SECURITY_INFORMATION 포함되어야 합니다.
개체를 만들 때 할당된 필수 레이블은 일반적으로 개체에 대한 올바른 무결성 수준이며 필수 레이블을 변경할 필요가 없습니다. 그러나 애플리케이션이 서로 다른 무결성 수준에서 여러 클라이언트 프로세스를 지원하도록 설계된 경우 개체의 무결성 수준을 변경하기 위한 애플리케이션 디자인 요구 사항이 있을 수 있습니다.
보안 설명자의 SACL에서 필수 레이블 ACE를 변경하는 데 필요한 권한은 WRITE_OWNER. SACL에 필수 레이블을 작성해도 SE_SECURITY_NAME 권한 또는 ACCESS_SYSTEM_SECURITY 액세스 권한이 필요하지 않습니다. 필수 레이블의 무결성 수준을 주체의 무결성 수준보다 작거나 같은 값으로 설정할 수 있습니다.
가장 일반적인 변경 내용은 개체의 무결성 수준을 낮추어 더 낮은 무결성 애플리케이션 프로세스에서 액세스 권한을 수정할 수 있도록 하는 것입니다. 예를 들어 중간 무결성 수준의 애플리케이션은 낮은 무결성 수준에서 실행되는 다른 애플리케이션 프로세스와 동기화해야 합니다. 중간 무결성 프로세스는 명명된 뮤텍스 개체를 만들고 낮은 값의 필수 레이블을 할당하여 낮은 무결성 프로세스가 뮤텍스를 열어 이벤트를 신호할 수 있도록 합니다.
레이블 다시 지정 권한
Windows 무결성 메커니즘은 SE_RELABEL_NAME 새 Windows 보안 권한을 정의합니다. 보안 액세스 토큰에서 사용하도록 설정하면 레이블 다시 지정 보안 권한을 통해 주체가 개체의 필수 레이블을 주체 액세스 토큰의 무결성 수준보다 높은 무결성 수준으로 설정할 수 있습니다. Windows Vista의 기본 보안 정책은 사용자 또는 그룹에 이 권한을 할당하지 않습니다. 이 권한은 높은 무결성 수준에서 실행되는 관리자 프로세스가 시스템 무결성 수준에서 개체에 대한 필수 레이블을 변경하거나 할당해야 하는 시나리오를 해결하기 위해 설계되었습니다. Windows Vista에는 다시 레이블 권한이 필요하거나 사용하는 작업이 없습니다.
Windows에서 개체에 필수 레이블을 할당하는 방법
Windows는 개체 보안 설명자를 만들 때 보안 개체에 필수 레이블을 할당합니다. 새 개체의 무결성 수준은 다음 세 가지 방법 중 하나로 할당됩니다.
- 보안 하위 시스템은 개체에 대한 보안 설명자를 만들 때 개체에 필수 레이블을 할당합니다.
- 만들기 프로세스는 CreateFile과 같은 함수를 사용하여 개체를 만들 때 명시적 필수 레이블을 보안 특성으로 지정합니다.
- 부모 컨테이너는 컨테이너에서 만든 자식 개체에 적용되는 상속 가능한 필수 레이블 ACE를 정의합니다.
개체 무결성 수준이 할당되는 방식을 이해하는 가장 쉬운 방법은 모든 개체에 만들기 프로세스(또는 스레드)의 주체 무결성 수준과 동일한 무결성 수준의 필수 레이블이 할당된다고 가정하는 것입니다. 그러나 개체 유형 및 주체 무결성 수준에 따라 일반적인 아이디어에는 예외가 있습니다. 예외는 UAC와 같은 다양한 보안 정책을 사용하거나 사용하지 않도록 설정된 경우 일관된 사용자 환경에 대한 다른 시스템 요구 사항을 지원하는 데 필요한 디자인 선택 사항의 결과입니다.
필수 레이블은 보안 설명자를 기반으로 액세스 제어가 있는 모든 보안 개체에 적용할 수 있습니다. 프로세스 및 스레드 개체, 명명된 개체, 파일 또는 레지스트리 키와 같은 영구 개체를 비롯한 다양한 유형의 보안 개체가 있습니다. Windows Vista는 개체를 만들 때 모든 개체 형식에 명시적 필수 레이블을 할당하지 않습니다. 보안 하위 시스템이 개체를 만들 때 필수 레이블을 할당하는 개체 형식은 다음과 같습니다.
- Process
- 스레드
- 액세스 토큰
- 작업
다른 모든 개체 형식에는 암시적 기본값 또는 상속된 필수 레이블이 있습니다. 액세스 토큰을 초기화하는 동안 무결성 수준이 대화형 로그온 중에 생성된 보안 액세스 토큰에 할당됩니다. 사용자 로그온을 대신하여 시작되는 첫 번째 프로세스는 explorer.exe 셸 프로세스를 시작하는 userinit.exe. Userinit.exe CreateProcessAsUser 호출을 사용하고 대화형 로그온 사용자에 대한 액세스 토큰을 전달하는 시스템 서비스(Winlogon)에서 시작됩니다.
CreateProcessAsUser는 프로세스 개체와 초기 스레드를 만듭니다. 프로세스 개체가 만들어지면 해당 프로세스의 보안 설명자에 새 프로세스에 대한 기본 액세스 토큰으로 할당된 액세스 토큰의 무결성 수준이 할당됩니다. userinit.exe CreateProcess를 호출하여 셸을 시작하면 explorer.exe 프로세스 개체가 초기화됩니다. 프로세스 개체에는 보안 설명자 및 기본 액세스 토큰이 포함됩니다. explorer.exe 프로세스의 필수 레이블은 userinit.exe 만들기 프로세스의 무결성 수준으로 설정됩니다. explorer.exe 대한 기본 액세스 토큰은 userinit.exe 부모 프로세스 만들기에서 상속되며 무결성 수준은 중간입니다. explorer.exe 프로세스에서 새 스레드를 만들면 스레드 개체에 보안 설명자가 제공되고 보안 하위 시스템은 만들기 프로세스의 무결성 수준에 따라 스레드 개체에 무결성 수준을 할당합니다. explorer.exe 프로세스 내의 스레드 개체에는 만들기 프로세스의 기본 액세스 토큰의 무결성 수준인 중간의 무결성 수준이 할당됩니다.
참고
액세스 토큰 개체는 자체 보안 설명자가 있는 보안 개체입니다. 토큰의 보안 설명자는 OpenProcessToken 또는 OpenThreadToken 함수 중에 허용되는 액세스를 확인하는 데 사용됩니다. 액세스 토큰 개체에는 액세스 토큰 개체의 보안 설명자에 필수 레이블이 있습니다. 액세스 토큰에는 주체 무결성 수준을 나타내는 액세스 토큰 그룹 목록에 무결성 수준 SID도 포함됩니다.
항상 프로세스, 스레드, 토큰 및 작업 개체에 필수 레이블을 할당함으로써 무결성 메커니즘은 낮은 무결성 수준의 동일한 사용자에 대한 프로세스가 이러한 개체 형식에 액세스하고 DLL 삽입 또는 상위 수준 액세스 토큰 가장과 같은 콘텐츠 또는 동작을 수정하지 못하도록 합니다.
기본 무결성 수준
모든 개체 형식에 보안 설명자에 필수 레이블 ACE가 할당되지는 않습니다. 필수 레이블 ACE가 보안 설명자에 있는 경우 이를 명시적 필수 레이블이라고 합니다. ACE라는 필수 레이블이 없으면 보안 하위 시스템은 필수 정책 검사 동안 해당 개체에 대해 암시적 기본 필수 레이블을 사용합니다. 기본 필수 레이블은 모든 보안 개체에 대해 중간 무결성 수준을 할당합니다. 보안 설명자에 필수 레이블이 정의되어 있지 않으면 암시적 기본 필수 레이블이 모든 개체 형식에 적용됩니다.
NO_WRITE_UP 기본 필수 정책과 결합된 중간의 기본 개체 무결성 수준은 주체 무결성 수준이 중간 미만인 프로세스에 따라 모든 개체에 대한 액세스 수정을 제한합니다. 기본 필수 레이블 및 정책은 낮은 무결성의 신뢰할 수 없는 프로세스가 DACL에서 임의 쓰기 액세스를 허용할 수 있는 시스템의 사용자 또는 시스템 파일 또는 레지스트리 키를 수정하지 못하도록 방지합니다.
NTFS 파일 시스템 개체 및 레지스트리 키는 생성될 때 자동으로 레이블이 지정되지 않습니다. 이전 버전의 Windows에서 Windows Vista로 업그레이드한 후에는 이러한 개체에 필수 레이블이 없습니다. 보안 설명자가 없는 비NTFS 파일 시스템(CDFS 또는 FAT32)의 파일은 보안 개체가 아니며 무결성 수준이 없습니다. 모든 보안 설명자에는 암시적 필수 레이블이 있어야 합니다.
중간 이상의 주체 무결성 수준을 가진 프로세스는 명시적 레이블 없이 파일 및 레지스트리 키를 만듭니다. 결과적으로 높은 또는 시스템 무결성 수준 프로세스에서 만든 파일 시스템 및 레지스트리 개체에는 암시적 중간 레이블이 있습니다. 필수 레이블을 사용하는 애플리케이션은 개체를 만들 때 명시적 레이블을 정의할 수 있습니다. 그러나 Windows Vista는 기본적으로 중간 무결성 수준보다 높은 레이블을 파일 시스템 또는 레지스트리에 할당하지 않습니다. 그렇다고 해서 이러한 개체가 반드시 낮은 무결성 프로세스에 의해 수정할 수 있도록 열려 있음을 의미하지는 않습니다. 상위 또는 시스템 수준 프로세스에서 만든 파일 시스템 또는 레지스트리 개체의 상속된(또는 기본) 임의 액세스 제어 목록은 Administrators 그룹의 멤버 또는 로컬 시스템 또는 서비스 계정에만 쓰기 권한을 부여합니다.
대부분의 개체 형식에 대해 주체의 무결성 수준에 따라 명시적 필수 레이블을 할당하는 대신 중간의 기본 암시적 필수 레이블을 사용하는 데 필요한 여러 가지 디자인 제약 조건입니다. 특정 예제는 로컬 보안 정책을 사용하여 사용자 계정 컨트롤을 사용하거나 사용하지 않도록 설정하는 기능을 기반으로 합니다. UAC를 사용하지 않도록 설정하면 로컬 관리자 그룹의 구성원인 사용자는 높은 무결성 수준에서 전체 권한 액세스 토큰으로 실행되는 모든 프로세스를 갖습니다. 모든 개체가 주체의 무결성 수준에서 명시적으로 레이블을 지정하는 경우 사용자가 만드는 문서 및 스프레드시트와 같은 모든 파일에 높은 무결성 수준이 할당됩니다. 사용자 프로필에 대한 상속된 DACL 권한이 사용자 액세스를 위한 충분한 액세스 제어를 제공하더라도 높은 레이블은 적절해 보입니다. 그러나 로컬 컴퓨터 또는 그룹 정책 UAC를 사용하는 경우 동일한 사용자가 실행하는 대부분의 프로세스에는 중간 무결성 수준에서 필터링된 보안 액세스 토큰이 할당됩니다. UAC를 사용하도록 설정한 후에는 UAC를 사용하지 않도록 설정할 때 생성된 파일을 열 수 없습니다. 사용자의 높은 무결성 문서를 열려고 시도한 중간 무결성 애플리케이션에는 액세스 거부 오류가 발생합니다.
프로세스가 중간의 기본 무결성 수준보다 작은 주체 무결성 수준으로 실행되는 경우 해당 프로세스는 암시적 중간 무결성 수준이 있는 모든 개체에 대한 액세스 권한이 제한됩니다. 무결성 수준이 낮은 프로세스는 DACL에서 보안 주체에 부여된 액세스 권한에 관계없이 명시적 또는 암시적 무결성 수준이 중간 이상인 개체를 수정할 수 없습니다. 따라서 주체 무결성 수준이 기본 수준(중간)보다 작은 프로세스에서 만든 모든 개체는 보안 하위 시스템에 의해 명시적으로 레이블이 지정됩니다. 모든 애플리케이션은 일반적으로 중간 무결성 수준에서 실행되고 애플리케이션 호환성 문제는 최소화되므로 Windows Vista에서는 낮은 무결성 프로세스에 대한 액세스 제한이 가능합니다. 낮은 무결성에서 올바르게 실행되는 애플리케이션은 일반적으로 제한된 액세스에서 제대로 작동하려면 특정 디자인 변경이 필요합니다. 디자인 변경 내용은 낮은 무결성 수준에서 실행할 애플리케이션 디자인의 아래 섹션에서 설명합니다.
낮은 주체에서 만든 개체 레이블 지정
애플리케이션은 낮은 무결성 수준에서 CreateProcessAsUser 함수를 사용하여 시작할 수 있습니다. 낮은 프로세스는 다음 무결성 수준 정보를 사용하여 CreateProcessAsUser에 의해 초기화됩니다.
- 새 프로세스 개체는 무결성이 낮은 필수 레이블을 포함하는 보안 설명자로 만들어집니다.
- 해당 프로세스 및 무결성이 낮은 필수 레이블을 포함하는 보안 설명자를 사용하여 새 스레드 개체를 만듭니다.
- 기본 액세스 토큰이 새 프로세스에 할당됩니다. 액세스 토큰 개체에는 필수 레이블이 낮은 보안 설명자가 있으며 액세스 토큰에는 주체 무결성 수준을 나타내는 낮은 무결성 SID가 있는 TokenIntegrityLevel이 포함됩니다.
낮은 무결성 프로세스가 실행 중이며 스레드를 만들려고 하는 것으로 가정합니다. 스레드를 만들려면 쓰기 액세스를 위해 자체 프로세스 개체를 열어 새 스레드 개체를 만들어야 합니다. 프로세스 개체의 필수 레이블이 중간인 경우 낮은 주체가 프로세스를 열지 못하고 새 스레드를 만들 수 없습니다. 프로세스 개체도 낮은 무결성으로 레이블이 지정되므로 낮은 주체는 쓰기 액세스를 위한 프로세스를 열고 새 스레드 개체를 만들 수 있습니다. 이 예제에서는 프로세스 개체, 스레드 개체 및 보안 액세스 토큰의 필수 레이블이 동일한 무결성 수준에서 일관되어야 하는 이유를 보여 줍니다.
참고
이는 낮은 주제뿐만 아니라 모든 무결성 수준에 적용됩니다.
낮은 프로세스에서 임시 파일을 만든다고 가정합니다. 애플리케이션은 CreateFile을 호출하여 새 파일을 만들고, 일부 데이터를 쓰고, 파일을 닫습니다. 나중에 낮은 프로세스는 동일한 파일을 다시 열어 데이터를 추가하려고 합니다. 임시 파일에 중간 무결성 수준에서 암시적 기본 필수 레이블이 있는 경우 낮은 프로세스는 액세스 수정을 위해 이전에 만든 파일을 다시 열 수 없습니다. 무결성 수준이 기본 수준 미만인 주체가 만드는 보안 개체에 대해 동일한 문제가 발생할 수 있습니다. 따라서 무결성 수준이 기본 수준 미만인 주체에서 만든 모든 보안 개체에는 명시적 필수 레이블이 자동으로 할당됩니다. 즉, 모든 커널 개체, 레지스트리 키 및 파일 시스템 개체는 주체 무결성 수준이 낮을 때 명시적으로 낮게 레이블이 지정됩니다.
특정 필수 레이블을 사용하여 개체를 만드는 방법
대부분의 Windows 애플리케이션은 "무결성 인식"일 필요가 없습니다. 보안 하위 시스템은 자동으로 개체를 만들고 필수 레이블을 할당합니다. 대부분의 애플리케이션은 중간 무결성 수준에서 실행되고 기본 개체 무결성 수준은 중간이므로 무결성 정책은 대부분의 애플리케이션에 허용되는 액세스 제어를 변경하지 않습니다. 그러나 서비스와 같은 일부 애플리케이션은 서로 다른 무결성 수준에서 클라이언트 애플리케이션을 지원하도록 설계되었습니다. 서비스가 클라이언트보다 높은 무결성 수준에서 실행 중일 수 있으며 클라이언트를 대신하여 만든 새 개체에 더 낮은 무결성 수준에서 명시적으로 레이블을 지정할 수 있습니다. 개체의 무결성 수준은 만들기 프로세스에서 설정할 수 있습니다. 제약 조건은 새 개체의 무결성 수준이 만들기 프로세스의 무결성 수준보다 작거나 같아야 한다는 것입니다.
특정 필수 레이블을 사용하여 개체를 만들려면 |
|
필수 레이블 상속
Windows Vista는 NTFS 파일 시스템의 파일 및 디렉터리에 명시적으로 레이블을 지정하지 않습니다. 앞에서 설명한 것처럼 보안 하위 시스템은 보안 설명자에 필수 레이블이 없는 개체에 대해 기본 수준 중간 수준의 암시적 필수 레이블을 사용합니다.
애플리케이션은 낮은 무결성 수준에서 실행되도록 설계할 수 있습니다. 보호 모드 인터넷 Explorer 낮은 무결성으로 실행되도록 설계된 Windows Vista 애플리케이션의 예입니다. 무결성이 낮은 애플리케이션에는 임시 파일 또는 애플리케이션 데이터를 쓸 수 있는 파일 시스템의 폴더가 필요할 수 있습니다. 보호 모드 인터넷 Explorer 경우 사용자 프로필의 임시 인터넷 파일 폴더가 사용됩니다. 낮은 애플리케이션은 파일 시스템 폴더에 어떻게 쓸 수 있나요? 폴더에는 낮은 무결성 프로세스에서 쓰기 액세스를 허용하는 명시적 필수 레이블이 할당되어야 합니다.
애플리케이션 디자인에 따라 낮은 무결성 애플리케이션에서 사용하는 폴더에 파일을 추가하는 다른 협력 프로세스가 있을 수 있습니다. 다른 프로세스도 낮은 무결성으로 실행되는 경우 해당 프로세스에서 만든 파일에는 낮은 필수 레이블이 자동으로 할당됩니다. 그러나 다른 파트너 프로세스의 무결성이 더 높은 경우 파트너 프로세스(파일 동기화 서비스 또는 사용자 에이전트)는 낮은 폴더에 자동으로 레이블이 지정되지 않은 파일을 만들 수 있습니다. 파트너 프로세스는 낮은 애플리케이션에서 사용하는 폴더에 중간 파일을 만듭니다. 이 파일은 낮은 애플리케이션에서 수정하거나 삭제할 수 없습니다.
무결성 메커니즘을 사용하면 필수 레이블이 낮은 폴더에 자식 개체, 파일 및 하위 폴더가 각각 다른 더 높은 필수 레이블을 가질 수 있습니다. 각 파일 시스템 개체에는 고유한 보안 설명자가 있기 때문입니다. 낮은 필수 레이블이 할당된 폴더의 경우 낮은 프로세스에서 수정할 수 있도록 폴더의 모든 파일에 낮은 필수 레이블을 할당해야 하는 많은 시나리오가 있습니다. 무결성 메커니즘은 필수 레이블 ACE를 부모 컨테이너에서 하위 컨테이너 및 자식 개체로 상속할 수 있도록 하여 이를 지원합니다.
필수 레이블 ACE 형식 데이터 구조에는 AceFlags 필드가 있는 ACE 헤더가 포함됩니다. AceFlags 필드는 임의 액세스에 사용되는 액세스 허용 ACE 형식과 같은 다른 ACE 형식의 상속 플래그와 동일한 ACE 형식에 대한 상속 플래그를 정의하는 데 사용됩니다. CI (컨테이너 상속) 및/또는 OI(개체 상속)의 경우 필수 레이블 ACE를 상속 가능으로 정의할 수 있습니다. 필수 레이블 ACE는 IO(inherit_only 수 없습니다). 컨테이너에 상속 가능한 필수 레이블 ACE가 할당된 경우 필수 레이블은 컨테이너 자체 및 상속이 적용되는 자식 개체에 적용됩니다.
상속 가능한 필수 레이블의 예는 모든 사용자 프로필에서 만든 폴더 중 하나에서 낮은 필수 레이블인 %USERPROFILE%\AppData\LocalLow입니다. 이 폴더는 프로필이 초기화되고 기본적으로 낮은 무결성 애플리케이션에서 쓸 수 있는 최상위 폴더로 의도될 때 낮은 필수 레이블이 할당됩니다. 다음 이미지는 Icacls 명령을 사용하여 표시되는 AppData\LocalLow 폴더의 상속 가능한 필수 레이블을 보여 있습니다. Icacls가 필수 레이블을 지원하는 방법에 대한 자세한 내용은 부록 B: Icacls 및 파일 무결성 수준을 참조하세요.
필수 레이블의 상속 플래그는 ACE가 NW(NO_WRITE_UP) 필수 정책이 있는 ACE(OI) 및 (CI) ACE임을 나타냅니다. AppData\LocalLow 폴더 아래에 만들어진 모든 하위 폴더는 상속 가능한 레이블을 상속합니다.
그림 4 상속 가능한 낮은 필수 레이블
중간 프로세스에서 새 파일 또는 하위 폴더를 만들면 새 개체는 낮은 필수 레이블을 상속합니다. 다음 예제에서는 명령 프롬프트가 중간 무결성 수준으로 프로세스에서 실행되고 있습니다. 파일, newfile.txt 및 새 폴더 Temp가 LocalLow 폴더에 만들어지고 두 개체 모두 부모 컨테이너에서 낮은 필수 레이블을 상속합니다. Icacls는 필수 레이블이 (I) 지정으로 상속됨을 나타냅니다.
그림 5 자식 개체의 필수 레이블 상속
필수 레이블에 대한 상속은 파일 시스템 네임스페이스의 일부에서 생성된 개체의 무결성 수준에서 일관성을 보장합니다.
상속 및 명시적 레이블
상속 가능한 필수 레이블이 있는 컨테이너에서 만든 개체는 컨테이너에서 필수 레이블을 상속합니다. 그러나 파일과 같은 새 개체를 만드는 프로세스는 CreateFile과 같은 create 함수에 보안 특성 매개 변수에 명시적 필수 레이블을 제공할 수 있습니다.
만들기 프로세스에서 명시적 레이블을 개체 만들기 함수에 대한 매개 변수로 제공하는 경우 새 개체에는 호출자가 제공한 명시적 필수 레이블이 할당되고 부모 컨테이너에서 상속되지 않습니다. 명시적 필수 레이블은 개체를 만드는 주체 프로세스보다 높은 무결성 수준을 가질 수 있습니다. 주체에서 제공하는 명시적 필수 레이블의 무결성 수준은 부모 컨테이너의 상속 가능한 필수 레이블의 무결성 수준보다 높을 수 있습니다.
상속 전용 제한
상속 전용(IO) 은 ACE가 연결된 개체에 대한 액세스를 제어하지 않음을 나타내는 액세스 제어 항목의 플래그입니다. 상속 전용 ACE는 일반적으로 컨테이너 개체에 할당됩니다. 상속 전용 ACE는 컨테이너 자체에 적용되지 않습니다. 오히려 컨테이너의 자식 개체에 적용됩니다. 새 개체에 INHERIT_ONLY 레이블을 설정하기 위한 기본값보다 무결성 수준이 낮은 주제에는 제한이 있습니다. 새 컨테이너 개체에 대해 전달된 명시적 레이블이 기본값보다 낮은 수준의 INHERIT_ONLY 레이블인 경우 레이블은 유효하지 않은 것으로 간주되고 무시됩니다. 이 제한의 근거는 낮은 주체가 컨테이너를 만들고 컨테이너의 INHERIT_ONLY 레이블을 낮게 설정하려고 한다는 것입니다. INHERIT_ONLY 레이블이 수락된 경우 컨테이너의 유효 무결성 수준은 암시적 기본 수준인 중간입니다.
또한 주체는 주체의 무결성 수준보다 높은 무결성 수준으로 INHERIT_ONLY 레이블을 정의할 수 없습니다. 예를 들어 중간 주제는 무결성 수준이 높은 INHERIT_ONLY 레이블을 정의할 수 없습니다.
보호된 SACL 및 레이블 상속
SDDL은 명시적 필수 레이블을 포함할 수 있는 보호된 SACL 정의를 지원합니다. 보호된 SACL은 보안 설명자의 SECURITY_DESCRIPTOR_CONTROL 필드에 SE_SACL_PROTECTED 플래그를 설정합니다. 액세스 권한과 관련된 LABEL_SECURITY_INFORMATION 및 SACL_SECURITY_INFORMATION 논리적 분리는 보호된 SACL의 작동 방식과 관련하여 완전하지 않습니다. 필수 레이블은 SACL에 저장됩니다. 보호된 SACL은 필수 레이블도 보호됨을 의미합니다.
SE_SACL_PROTECTED 플래그가 SECURITY_DESCRIPTOR_CONTROL 설정된 경우 필수 레이블도 보호됩니다.
- 보호된 SACL에 필수 레이블 ACE가 없으면 컨테이너의 상속 가능한 필수 레이블 ACE가 적용되지 않습니다(새 개체에는 암시적 기본 필수 레이블이 있음).
- 보호된 SACL에 필수 레이블 ACE가 있는 경우 컨테이너의 상속 가능한 레이블 ACE에 대한 변경 내용은 이 개체에 영향을 미치지 않습니다.
SDDL에 대한 자세한 내용은 부록 A: 필수 레이블용 SDDL 또는 Windows 무결성 메커니즘 리소스를 참조하세요.
필수 정책에서 액세스 확인이 작동하는 방법
AccessCheck 함수는 필수 정책을 적용합니다. AccessCheck는 지정된 보안 설명자를 지정된 액세스 토큰과 비교하고 AccessStatus 매개 변수에서 액세스 권한이 부여 또는 거부되었는지 여부를 나타냅니다. AccessCheck 함수는 먼저 ClientToken 의 무결성 수준을 pSecurityDescriptor 의 SACL에 있는 필수 레이블과 비교하여 필수 정책에 따라 사용할 수 없는 액세스 권한을 결정합니다. 필수 정책이 검사 후에 AccessCheck는 원하는 액세스 권한을 DACL에 부여된 액세스 권한과 비교합니다.
기본 필수 정책은 낮은 무결성 프로세스가 더 높은 무결성 개체에 대한 일반 쓰기 액세스 권한을 얻지 못하도록 방지합니다. 예를 들어 기본적으로 낮은 무결성 프로세스는 더 높은 무결성 수준을 가진 개체에 대한 일반 쓰기 액세스가 거부됩니다. pSecurityDescriptor에 필수 ACE가 없는 경우 개체에 중간 무결성 수준을 할당하는 암시적 필수 ACE가 있다고 가정합니다. GenericMapping 매개 변수는 제네릭 쓰기 액세스와 연결된 액세스 권한을 결정합니다. GenericMapping 매개 변수가 모두 0이면 무결성 검사 낮은 무결성 ClientToken에 대한 특정 액세스 권한을 부여하지 않습니다. 무결성 검사 필수 정책에 따라 호출자가 사용할 수 있는 일반 액세스 권한을 결정하면 보안 설명자의 DACL이 ClientToken과 비교하여 부여된 나머지 액세스 권한을 결정합니다.
UIPI(사용자 인터페이스 권한 격리) 및 무결성
UIPI(사용자 인터페이스 권한 격리)는 하위 권한 애플리케이션이 창 메시지를 보내거나 높은 권한 프로세스에서 후크를 설치하지 못하도록 하는 Windows 하위 시스템의 제한을 구현합니다. 더 높은 권한의 애플리케이션은 낮은 권한 프로세스로 창 메시지를 보낼 수 있습니다. 제한 사항은 SendMessage 및 관련 창 메시지 함수에서 구현됩니다. 낮은 권한 프로세스에서 더 높은 권한 프로세스로 전송되는 모든 창 메시지가 차단되지는 않습니다. 일반적으로 "읽기" 형식 메시지(예: WM_GETTEXT)는 낮은 권한에서 더 높은 권한 창으로 보낼 수 있습니다. 그러나 WM_SETTEXT 같은 쓰기 형식 메시지는 차단됩니다.
UI 권한 수준은 프로세스 수준에 있으며 프로세스에서 만든 모든 창에 적용됩니다. USER 하위 시스템은 프로세스가 Windows GDI(그래픽 디바이스 인터페이스)를 처음 호출할 때 초기화됩니다. 프로세스 초기화 중에 USER 하위 시스템은 에서 보안 하위 시스템을 호출하여 프로세스의 기본 보안 액세스 토큰에 할당된 무결성 수준을 결정합니다. USER 하위 시스템이 프로세스 초기화 중에 UI 권한 수준을 설정한 후에는 변경되지 않습니다. 스레드의 TokenIntegrityLevel을 더 낮은 값으로 설정해도 프로세스의 UI 권한 수준이나 해당 프로세스 또는 스레드에서 연 창에는 영향을 주지 않습니다.
UIPI는 동일한 권한(또는 무결성) 수준에서 애플리케이션 간의 창 메시징 동작을 방해하거나 변경하지 않습니다. UIPI는 다음 동작을 차단하여 낮은 권한 프로세스에서 더 높은 권한 프로세스에 액세스하지 못하도록 방지합니다. 낮은 권한 프로세스는 다음을 수행할 수 없습니다.
- 더 높은 권한으로 실행되는 프로세스의 창 핸들 유효성 검사를 수행합니다.
- SendMessage 또는 PostMessage를 사용하여 더 높은 권한으로 실행되는 애플리케이션 창에 사용합니다. 이러한 API는 성공을 반환하지만 창 메시지를 자동으로 삭제합니다.
- 스레드 후크를 사용하여 더 높은 권한으로 실행되는 프로세스에 연결합니다.
- 저널 후크를 사용하여 더 높은 권한으로 실행되는 프로세스를 모니터링합니다.
- 더 높은 권한으로 실행되는 프로세스에 동적 연결 라이브러리(DLL) 삽입을 수행합니다.
UIPI를 사용하도록 설정하면 다음과 같은 공유 사용자 리소스가 서로 다른 권한 수준의 프로세스 간에 공유됩니다.
- 화면 화면을 실제로 소유하는 바탕 화면 창
- 데스크톱 힙 읽기 전용 공유 메모리
- 전역 원자 테이블
- 클립보드
화면에 그리는 작업은 UIPI에 의해 차단되지 않는 또 다른 작업입니다. 사용자/그래픽 GDI(디바이스 인터페이스) 모델은 그리기 표면을 제어할 수 없습니다. 따라서 더 적은 권한으로 실행되는 애플리케이션이 더 높은 권한으로 실행되는 애플리케이션에 대해 애플리케이션 창의 표면에 그릴 수 있습니다.
UI 자동화 애플리케이션에 대한 UIAccess
Microsoft UI 자동화는 MSAA(Microsoft Active Accessibility)라고 하는 이전 모델보다 향상된 접근성 요구 사항을 지원하는 Windows Vista 모델입니다. 액세스 가능한 사용자 환경을 지원하도록 설계된 애플리케이션은 사용자를 대신하여 다른 Windows 애플리케이션의 동작을 제어합니다. 모든 애플리케이션(자동화 클라이언트 및 서버)이 표준 사용자로 실행되는 경우, 즉 중간 무결성 수준에서 UIPI 제한은 UI 자동화 모델을 방해하지 않습니다.
그러나 관리자가 관리 승인 모드에서 UAC에 따라 상승된 권한으로 애플리케이션을 실행하는 경우가 있을 수 있습니다. UI 자동화 프로그램은 UIPI가 구현하는 제한을 무시할 수 없으면 데스크톱에서 상승된 애플리케이션의 그래픽 UI를 구동할 수 없습니다. 권한 수준에서 SendMessage에 대한 UIPI 제한을 우회하는 기능은 UIAccess라고 하는 프로그램의 애플리케이션 매니페스트에서 특수 보안 특성을 사용하여 UI 자동화 프로그램에 사용할 수 있습니다.
다음은 UIAccess 프로그램에 대한 애플리케이션 매니페스트 항목의 예입니다.
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel
level="asInvoker"
UIAccess="true" />
</requestedPrivileges>
</security>
</trustInfo>
requestedPrivileges 특성에 UIAccess="true" 를 지정하여 애플리케이션은 권한 수준에서 창 메시지를 보내는 데 대한 UIPI 제한을 우회해야 한다는 요구 사항을 명시하고 있습니다. Windows Vista는 UIAccess 권한으로 애플리케이션을 시작하기 전에 다음 정책 검사를 구현합니다.
- 애플리케이션에는 로컬 컴퓨터 신뢰할 수 있는 루트 인증 기관 인증서 저장소의 신뢰할 수 있는 루트까지 연결된 디지털 인증서를 사용하여 확인할 수 있는 디지털 서명이 있어야 합니다.
- 애플리케이션은 Program Files 디렉터리 같은 관리자만 쓸 수 있는 로컬 폴더 애플리케이션 디렉터리에 설치해야 합니다. UI 자동화 애플리케이션에 허용되는 디렉터리는 다음과 같습니다.
- %ProgramFiles% 및 하위 디렉터리
- %WinDir% 및 하위 디렉터리(표준 사용자가 쓰기 권한을 가지고 있기 때문에 제외되는 몇몇 하위 디렉터리 제외)
제외된 하위 디렉터리인 %WinDir% 하위 디렉터리에는 다음이 포함됩니다.
- \디버그
- \PCHealth
- \등록
- \System32\ccm
- \System32\com
- \System32\FxsTmp
- \System32\Spool
- \System32\Tasks
Windows Vista는 로컬 컴퓨터 정책 및 그룹 정책 보안 위치에서 UIAccess 프로그램을 시작해야 한다는 요구 사항을 조정하기 위한 보안 설정을 제공합니다. 설정은 로컬 보안 정책에 대한 로컬 정책 아래의 보안 옵션 아래에 정의됩니다. 보안 정책은 다음과 같습니다.
사용자 계정 컨트롤: 보안 위치에 설치된 UIAccess 응용 프로그램만 권한 상승
이 설정은 기본적으로 사용하도록 설정됩니다. 그러나 폴더에서 시작해야 하는 UIAccess 애플리케이션(접근성 기술)이 관리자 전용 쓰기 액세스로 보호되지 않는 경우 관리자가 사용하지 않도록 설정할 수 있습니다.
UIAccess를 요청하는 UI 자동화 애플리케이션이 UIAccess 설정 요구 사항을 충족하는 경우 Windows Vista는 대부분의 UIPI 제한을 무시할 수 있는 기능을 사용하여 애플리케이션을 시작합니다. UI 자동화 애플리케이션이 보안 제한을 충족하지 않는 경우 애플리케이션은 UIAccess 권한 없이 시작되며 동일하거나 낮은 권한 수준에서만 애플리케이션과 상호 작용할 수 있습니다.
UIAccess 권한으로 시작되는 프로세스:
- 포그라운드 창을 설정할 수 있습니다.
- SendInput 함수를 사용하여 애플리케이션 창을 구동할 수 있습니다.
- 하위 수준 후크, 원시 입력, GetKeyState, GetAsyncKeyState 및 GetKeyboardInput을 사용하여 모든 무결성 수준에 대한 읽기 입력이 있습니다.
- 저널 후크를 설정할 수 있습니다.
- AttachThreadInput을 사용하여 스레드를 더 높은 무결성 입력 큐에 연결
표준 사용자에 대한 UIAccess 권한으로 시작된 애플리케이션에는 액세스 토큰에 약간 더 높은 무결성 수준 값이 할당됩니다. 표준 사용자에 대한 UIAccess 애플리케이션에 대한 액세스 토큰 무결성 수준은 중간 무결성 수준의 값과 0x10 증가입니다. UIAccess 애플리케이션의 무결성 수준이 높을수록 중간 무결성 수준에서 동일한 데스크톱의 다른 프로세스가 UIAccess 프로세스 개체를 열지 못하게 됩니다.