본문 바로가기

IT 살이/03. 관리 - 보안 관리

[연재 03] Deeper into the UAC

앞의 포스트를 요약해보면 다음과 같다. "관리자 권한이 필요한 프로그램이 권한 관련해서 에러없이 실행되도록 하려면, 1) 사용자가 관리자 계정으로 프로그램을 실행시키든지 2) 프로그램 자체가 관리자 계정으로 실행되어야 한다는 것을 Windows에게 알려줄 수 있어야 한다. 여기까지는 나름대로 깔끔한 정리이다. 그러나 구체적으로, 언제 UAC에게 언제 어떻게 관리자 토큰을 사용하라고 일러줄 수 있는지에 대한 질문들이 남아있다. 그 질문에 대한 답을 바로 들어가기 전에 이 포스트에서는 토큰(token)의 구조를 좀 더 깊게 알아보자. 어떻게 보면 프로그래밍과는 직접적인 관계는 없으나 보안과 관련된 지식으로써 알아두면 나중에라도 도움이 될 것이다.

토큰(Token)의 구조

토큰은 사용자가 로그온을 하게 되면 그 사용자를 대표해서 컴퓨터의 RAM에 자리를 잡게되는 데이터 구조를 말한다.  Vista 토큰도 이전 Windows의 토큰과 비슷한 구조로서 몇개의 항목으로 구성된다 : 사용자 이름, 사용자 그룹 멤버쉽, 사용자 권한, Windows integrity level.

1270270964

[그림] 토큰 구성 요소

전문가의 눈에는 달봉이의 Windows 보안에 대한 지식이 초보 수준일 것이다. 그러나 개발자 입장에서 토큰이 뭣이고 어떤 구조로 되어 있는가를 개략적으로나마 이해하는 것은 UAC를 이해하는 데 있어서 중요한 문제일 것이라 본다.

■ 사용자 이름 : Security ID(SID)

물론 컴퓨터 내부에서는 실제의 사용자 이름을 사용하지는 않는다. 실세계에서는 동명이인이 있을 수 있지만, Windows에서는 고유해야 하고 그것을 이름하여 Security ID 즉 SID라고 한다. 사용자나 그룹의 SID는 다음과 같은 모양으로 되어 있다.

S-1-5-21-domainID - relativeID

여기서 domainID는 사용자 계정의 위치 즉 특정 도메인이나 머신을 나타내는 96bit 숫자이고 relativeID는 그 위치에서의 특정 계정을 구분하는 숫자이다. 도메인이 생성되면 이전에도 없었고 앞으로도 없을 고유한 ID가 그 도메인에 부여된다. 그 값을 비록 있을 수 없는 숫자이지만 "12345"라고 하자. 그럼 그 도메인에 생성되는 달봉이 계정에는 다음과 같은 모양의 SID가 부여될 것이다: "S-1-5-21-12345-relativeID". relativeID는 1000부터 시작하게 되는데 첫번째 사용자 달봉이 계정이 생성되면 그 SID는 "S-1-5-21-12345-1000"이 되고 그 다음 사용자는 "S-1-5-21-12345-1001"이 될 것이다. SID를 생성하는 규칙은 좀 더 복잡하지만 하여튼 컴퓨터 관점에서는 이 SID를 통해서 컴퓨터 계정이든 사용자 계정을 구분하게 된다.

만약 달봉이가 어떤 파일이나 폴더에 대해 특별한 권한(permission)을 가지고 있다면 NTFS에는 "달봉이가 C:\dalbongstuff에 풀권한을 갖는다"라고 저장되지 않는다. 대신에 "S-1-5-21-12345-r1000이 C:\dalbongstuff에 풀권한을 갖는다"라고 표현되어 저장된다(물론 "풀권한을 갖는다"고 텍스트로 저장되지는 않는다 ^^).

가끔 보면 rights , privilages, permissions이 모두 권한으로 번역되는 문서가 있다. 대체 이것들은 어떤 차이가 있을까. 달봉이도 평소 아무 생각없이 쓰다 함 의미를 정확인 구분해 보고 싶었다. 검색을 하다가 마이크로소프트에서 해당 용어들을 정의해 놓은 페이지를 찾았다. 간단하게 요약하자면 이렇다. 우선 이 세 용어는 다음처럼 분류될 수 있다.  permissions과 User Rights로 분류되고 User Rights는 다시 Logon Rights와 Privileges로 나뉜다. Permission은 파일이나 폴더가 같은 특정 개체에 대해서 오퍼레이션을 수행할 수 있는 권한을 말하고 User rights는 컴퓨터의 특정 개체보다는 컴퓨터 전체에 영향을 미칠 수 있는 오퍼레이션을 수행할 수 있는 권한을 말한다. 그 중에서 Logon rights는 사용자 또는 보안 주체(security principals)에 대해서 어떤 로그온 방식을 제어할 것인가를 결정한다. 그리고 그 외의 사용자 권한으로 privilegs는 어떤 사용자가 컴퓨터 전체에 영향을 미칠 수 있는 리소스 조작을 할 수 있는지를 결정한다. permission은 개체를 소유하고 있는 소유자에 의해서 설정되며 그 권한 정보는 개체별로 저장된다. 반면에 User rights는 컴퓨터의 전체적인 보안 정책(security policy) 설정을 통해서 저장된다. 앞에서 소개한 링크 페이지에서 이것들에 대한 샘플 권한들을 보면 좀 더 그 차이를 알 수 있게 된다.

■ 사용자 그룹 멤버십 : SID 목록

토큰은 SID 뒤에 사용자가 멤버로 등록되어 있는 그룹들에 대한 목록 정보를 가지고 있다.

Domain-based global groups

Domain-based univeral groups

Domain-based domain local groups

Built-in local groups( Administrators, User groups)

기타 사용자가 시스템에 추가하는 로컬 그룹  등

■ 사용자 권한(Privileges) : What You Can Do

Windows는 사용자에게 파일이나 폴더같은 특정 객체에 접근해서 읽고 쓸 수 있는 권한을 허용할뿐만 아니라 컴퓨터 전체를 상태로 해서 어떤 일을 할 수 있는 권한도 부여한다. 특정 개체에 대한 권한을 permission이라고 한다면 이처럼 어떤 작업(task)를 수행할 수 있는 권한을 previlege라고 한다. 앞에서 소개한 링크 페이지를 참조하라.  이 privilege를 표현할때는 보통 문서에서는 두 가지 방식으로 표현한다. 하나는 텍스트 기반의 설명이고 다른 하나는 "SeXXX"형태의 짧은 이름이다. Vista에서는 이전 Windows에서 사용하던 privilegs 표현을 그대로 사용하고 있고, 예를 보면 다음과 같다.

SeShutdownPrivilge : 시스템을 종료할 수 있는 권한

SeBackupPrivilege와 SeResotrePrivilege : 파일, 폴더를 복사하고 복원할 수 있는 권한.

이전의 Windows에서 사용한 것을 많은 부분 그대로 이어받아서 Vista에서는 미리 정의된 34가지 유형의 privileges와 10가지의 logon rights를 정의하고 있다.  이중에서 UAC는 보안적인 측면에서 안전한 5가지 privilegs만 허용한다. 여기서는 개념적으로만 이해하고 구체적으로 어떤 privileges가 있고 그 중에서 어떤 것들이 UAC하의 사용자 계정에 부여되었는지는 다른 문서를 참고하도록 한다.

■ Windows Integrity Level

이것은 이전 Windows에서는 없던 토큰의 새로운 구성요소이다. Windows가 사용자를 "어느정도 신뢰하는가"를 나타내는 값이다. 이 신뢰도를 마이크로소프트에서는 Integrity라는 단어로 표현하고 있다. 신뢰도는 6단계로 구분되지만 UAC와 관련해서는 두 단계 "medium", "high" Windows Integrity Level만 사용된다. 일반 사용자 계정은 medium레벨을 얻게되고, 관리자는 high 레벨을 얻게 된다. SID의 표현중에서 "S-1-16-value"와 같은 부분이 Windows Interity Level을 나타내는 부분이다. 여기서 value는 medium인 경우는 8192, high인 경우는 12,288로 표현된다. Windows Integrity Level를 제어한다는 개념(WIC, Windows Integriy Control)도 Vista에서 나온 새로운 개념으로 할 말이 꽤 있는 모양이다. 

■ 사용자 토큰 정보를 알아보자.

토큰이 이런 구성 요소들로 이뤄졌다고 것이고, Vita에서는 이런 토큰을 살펴 볼 수 있는 커맨드 라인 툴을 제공해 주고 있다. 커맨드 프롬프트창을 실행시켜 다음 명령을 수행하면 내가 로그온한 후 생성된 토큰의 모양을 볼 수 있다.

whoami /user

1289695371

[그림] 일반 사용자 계정의 SID 정보

사용자 계정이 속한 그룹에 대한 정보를 보고 싶다면 다음 명령어를 입력한다.

whoami /groups

1122358351

[그림] 그룹 정보

그림을 보면 "Manatory Label\Meduum Manatory Level"로서  "S-1-16-8192"로 출력된다. 즉 "Windows Integrity level"이 "medium"이라는 Vista식 표현이다.  그리고 "BUILTIN\Administrators"그룹의 특성의 값이 "거부 대해서만 그룹 사용"이라고 표시되어 있다. 즉 일반 사용자 토큰으로 로그온한 경우는 "deny"인 경우만 Administrators그룹에 속한 것이다라는 얘기다. 말이 좀 이상하게 들릴지 모르지만 이 얘기는 UAC가 일반 사용자 토큰에서는 "BUILTIN\Administrators" 그룹의 멤버십을 없앴다는 얘기로 보면 된다.

사용자 권한을 알아볼 수도 있다.

whoami /priv

1385068128

[그림] 사용자 권한

앞에서 본 명령을 이제 "관리자 권한으로 실행"된 프롬프트창에서 실행해본다. 그리고 그 값들을 앞에서의 결과들과 비교해 본다. Elevated된 후의 정보들이 출력됨을 볼 수 있을 것이다.

1105290442

[그림] 권한 상승 후의 사용자 SID

권한 상승후 라도 현재 로그인한 사용자가 변경된 것은 아니다. 해서 이미 로그온한 사용자의 사용자 계정 정보는 변함없다.

"관리자 권한으로 실행"된 프롬프트창에서 whoami /groups를 실행시켜보면 다음과 같은 결과가 나온다.

1338990631

[그림] 권한 상승후의 Windows Integrity Level 값

관리자 권한으로 명령 프롬프트창을 실행한 후를 보면 "Mandatory Label\High Mandatory Level임을 알수 있다.  그리고 "BUILTIN\Administrators"그룹에 대해서 특성값을 보면 "필수 그룹, 기본값으로 사용 가능"으로 되어 있다. 이 얘기는 "BUILTIN\Administrators"그룹의 멤버십과 권한을 복원했다고 보면 된다.

이제 다음 포스트에서는 사용자가 프로그램을 관리자 권한으로 실행하는 일반적인 방법 그리고 아마 그 다음 포스트에서는 개발자들이 프로그램을 개발할때 관리자 권한이 필요하다는 것을 Vista에게 알리도록 표시하는 방법을 알아보게 될 것이다.