본문 바로가기

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

[연재 05] Vista가 자동으로 관리자 토큰을 사용하도록 하는 방법

프로그램이 실행되는 도중에 권한 부족으로 프로그램이 중단되었다는 메세지는 신뢰도에 치명적이지 않을 수 없을 것이다. 그렇다면 프로그램이 시작되기 전에 관리자 권한이 필요하다는 것을 어떻게 UAC에게 알릴 것인가에 대한 것이 달봉이가 이전 포스트에서부터 기록하고 싶은 주제중의 하나이다. 그렇다고 동의 확인 창 또는 관리자 계정 요청 창이 뜨게 하지 않을 수는 없다. 관리자 권한이 필요하다면 사용자로부터의 확인을 요하는 창은 뜨게 되어 있다. 결국 개발자는 어떻게 하면 이 확인창을 뜨게 할 것인가를 고민해야 하는 것이 이 포스트들의 주요 내용이라고 할 수 있다.

앞 포스트에서는 사용자가 직접 Vista(UAC)에게 관리자 토큰을 사용하도록 하는 하는 방법에 대해서 알아봤다. 이번 포스트에서는 프로그램을 실행시킬때 UAC가 관리자 권한의 토큰이 필요하다는 것을 스스로 인식할 수 있는 방법에 대해서 알아본다. 관리자 권한이 필요하다는 것을 감지하게 되면 자동으로 권한 상승이 필요하게 되어서 사용자가 프로그램을 오른쪽 클릭해서 "관리자 권한으로 실행"을 선택하지 않더라도 동의 확인(Consent UI) 프롬프트를 보여주게 된다. 이렇게 할 수 있는 방법으로는 다음과 같은 4가지 경우가 있겠다.

▶ 개발자가 직접 실행 프로그램 EXE의 메너페스트 파일에 애플리케이션의 권한 상승이 필요하다는 사실을 표시해서 Vista에게 알려줄 수 있는 방법이 있다. 메너페스트 파일은 프로그램에 임베딩될 수도 있다.

▶ 만약 실행되는 프로그램이 어플리케이션 인스톨러라고 추측을 하게 되면 Vista는 권한 상승을 수행하게 된다. 보통 인스톨러는 보호를 받는 레지스트리나 디스크에 접근해서 쓰는 작업을 하기 때문이다.

▶ Vista의 윈도우 탐색기 또는 IE에는 PCA(Program Compatibility Assistant)라 불리는 것이 있다. 이것은 Vista이전의 프로그램을 실행하려고 하면 호환성 문제를 조사한다. 만약 그런게 발견되면 사용자에게 권한 상승이 필요한 프로그램이라는 마크를 달아둘 것인지를 묻는다. 사용자가 승인을 하게 되면 Vista이전의 그 프로그램은 권한 상승이 필요하다는 것을 레지스트리에 저장한다. 그때부터 이제 사용자가 그 프로그램을 실행시킬때마다 동의 확인 프롬프트창이 뜨게 된다.

▶ Vista에는 Application Compatibility Database라는 것을 가지고 있는데, 이것에는 권한 상승이 일어나지 않으면 실패하게 되는 과거의 프로그램들에 대한 목록이 들어 있다. 만약 사용자가 그런 프로그램들중의 하나를 실행시키면 UAC는 자동으로 동의 확인창을 띄우게 된다.

이중에서도 처음 1가지가 개발자와 직접적으로 관련된 것이고 나머지 3가지는 Vista에 내재되어 있는 자동 감식 기능이다.  이번 포스트에서는 첫번째에 대한 이야기를 정리하고 뒤의 3가지에 대해서는 다음 포스트에서 알아보도록 하겠다.

■ 권한 설정 내용을 포함하는 메너페스트를 인식할 수 있는 Vista

.NET를 공부하면서 이미 메너페스트라는 말을 많이 들어본 개발자들도 많이 있을 것이다. 어셈블리 메너페스트 그리고 ClickOnce에서는 어플리케이션 메너페스트, 배포 메너페스트등. 메너페스트라는 것은 OS에게 어플리케이션을 로딩하고 실행시키는 것에 대한 여러 정보를 알려 줄 수 있는 어플리케이션과 관련된 작은 텍스트 파일을 말한다. 그것들은 실행파일(어셈블리)에 임베딩될 수도 있고 또는 실행 파일의 외부에 별도의 파일로 존재할 수도 있어서 노트패드같은 편집기로 편집을 할 수도 있다. 메너페스트에는 많은 정보들이 있을 수 있지만 ▷해당 어플리케이션은 어떤 버전의 DLL을 필요로 하는가 ▷어플리케이션은 어떤 토큰을 필요로 하는가(일반 사용자 토큰 또는 관리자 권한 토큰)같은 사실들을 OS에 알려줄 수 있다.

원래 메너페스트는 XP에서 나타났는데, "Windows Side by Side"라는 것을 소개하면서 처음으로 메너페스트를 중요하게 사용하게 되었다. MSDN의 내용을 그대로 옮기면 다음과 같다. "Side-by-side 실행은 동일한 컴퓨터에서 여러 버전의 응용 프로그램 또는 구성 요소를 실행하는 기능입니다. 동일한 컴퓨터에서 여러 버전의 공용 언어 런타임과, 하나의 런타임 버전을 사용하는 여러 버전의 응용 프로그램 및 구성 요소를 동시에 사용할 수 있습니다" Side by Side라는 것은 이전 OS에서의 "DLL hell" 문제를 해결할 수 있는 훌륭한 방안으로 소개되었다. 버전이 다른 DLL을 함께 가지고 있어서 어플리케이션이 원하는 DLL을 사용하게 되면 문제를 해결할 수 있게 되는 것이다. 메너페스트를 OS에게 원하는  DLL의 버전을 알려줄 수 있는 수단으로 사용할 수 있는 것이다.

Vista에서도 메너페스트 파일을 관리하는 것은 여전히 Windows Side by Side에서 담당한다. 만약 메너페스트와 관련된 에러가 발생하면 Vista의 이벤트 뷰어에서 어플리케이션 폴더에 "SideBySide"라는 소스로해서 에러가 출력될 것이다.

만약 메너페스트를 EXE 또는 DLL에 임베딩시키지 않고 외부의 파일로 만든다면 다음과 같이 해서 특정 어플리케이션과 메너페스트를 연결해줘야 한다.

▷먼저 Exe 파일이 있는 디렉토리에 메너페스트 파일을 둬야 한다.

▷둘째 메너페스트 파일명은 반드시 "어플리케이션명.exe.manifest" 형태로 되어 있어야 한다.

만약 어떤 어플리케이션이 임베딩된 메너페스트와 외부의 파일로 존재하는 메너페스트를 모두 가지고 있다면 어떻게 될까. 그런 경우에는 Windows는 외부 메너페스트를 무시하고 내부 메너페스트만 사용하게 된다.

■ 기존 메너페스트 살펴보기

그럼, 지금 사용되고 있는 메너페스트를 한번 살펴보도록 하자. net.exe 프로그램에 임베딩된 메너페스트를 살펴보도록 할텐데 프로그램에 임베딩된 메너페스트를 보여줄 수 있는 프로그램이 필요하다. 임베딩된 메너페스트도 다른 리소스처럼 취급되는데 리소스 편집기를 이용해서 그 내용을 볼수 있다. 다음 링크를 따라가면 무료의 리소스 편집기를 얻을 수 있다. http://www.wilsonc.demon.co.uk 사이트를 통해서 얻을 수도 있고 "XN Resource Editor"라는 단어로 구글링해서 나오는 검색 결과를 통해서도 얻을 수 있다.

1401752615

[그림] XN 리소스 편집기 실행 모습

1184361366

[그림] net.exe를 로드한 XN 리소스 편집기 모습

메너페스트는 XML로 되어 있는데 지금 중요한 것은 다음과 같은 부분이다.

<requestedExecutionLevel

    level="asInvoker"

    uiAccess="false"

/>   

마이크로소프트의 명명 규칙에 익숙한 개발자들은 "requestExecutionLevel"을 "RequestExcutionLevel"로 바꾸고 싶겠지만 그렇게 하면 에러가 된다. xml에서는 대소문자를 구분한다는 것에  주의한다. 어트리뷰트 level의 값이 개발자가 관심이 있는 부분인데 이곳이 UAC에게 어플리케이션의 권한 상승이 필요한지를 알려줄 수 있는 부분이다. 이 값은 다음 3가지를 취할 수 있다.

asInvoker : 이 값을 이용하면 프로그램은 UAC에게 다음과 같은 내용을 전달하는 것으로 풀이할 수 있다:"나를 실행시킨 사용자가 가지고 있는 토큰을 그대로 사용해라" 프로그램을 로그온된 그대로의 계정을 사용해서 실행시킨면 일반 사용자 토큰을 사용하게 될 것이고 권한이 상승된 상태에서 프로그램을 실행시켰다면 관리자 토큰을 사용하게 될 것이다.

highestAvailable : 이 값은 "사용자가 가지고 있는 토큰중에서 가장 높은 권한을 토큰을 프로세스에 부여하라. 만약 필요하다면 동의 확인창(Consent UI)을 띄워서 필요한 레벨의 토큰을 구해라"라는 의미를 UAC에 전달한다.

requireAdministrator : 이것은 "highestAvailable"과 같지만 관리자 권한이 토큰이 필수적으로 필요하다는 의미이다. "사용자가 가지고 있는 토큰중에는 반드시 관리자 토큰이 있어야 한다. 그렇지 않으면 사용자에게 물을 필요도 없이 어플리케이션 실행을 그만 둬라"라는 의미이다.

마지막 두 값의 차이점은 뭘까. 하나의 토큰은 분리된 권한을 가지고 있을 수 있다. 그러나 두 토큰이 모두 관리자 권한의 토큰이 아닐 수 있다( 사실 어떻게 그렇게 될 수 있는 지에 대해서는 달봉이도 모른다.) 따라서 가장 높은 토큰을 사용한다고 해도 관리자 토큰이 아닐 수도 있다. 그래서 만약 어플리케이션을 관리자 권한의 토큰으로 실행시키고자 한다면 반드시 level="requireAdministrator"로 설정해야 한다.

프로그램을 어떤 토큰으로 실행시켜야 하는지에 대한 의도를 Vista에 알리는 메커니즘을 알았다. 그럼 이제 실제로 어떻게 하면 메너페스트 내용을 UAC가 알 수 있도록 하나. 세가지 방법이 있을 수 있다.

▶리소스 편집기로 메너페스트 추가하기

1) XN 리소스 편집기를 실행시킨다.

2) Add Resource 선택->리소스 선택창에서 "XP Theme Manifest" 선택

1205513168

[그림] XN 리소스 편집기_리소스 추가

3) 기본적으로 오른쪽 창에 나타나는 코드를 선택해서 모두 지운다.

4) 오른쪽 창에 다음 코드를 붙여넣기 한다.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

    <assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="simple" type="win32"/>


    <description>Simple output app</description>


    <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">

        <security>

            <requestedPrivileges>

                <requestedExecutionLevel level="requireAdministrator"/>

            </requestedPrivileges>

        </security>

    </trustInfo>


</assembly>

5) 편집된 리소스를 저장한다.

▶외부 파일로 메너페스트 정보 추가하기

두번째 방법은 훨씬 더 쉽다. "어플리케이션.exe.manifest"라는 이름으로 텍스트 파일을 만들어서 첫번째 방법에서 보여준 XML 내용을 그 파일에 옮겨놓고 저장한다. 그런 다음 그 파일을 실행파일이 있는 곳에 둔다. 그럼 Vista는 임베딩된 메너페스트 내용이 없는 경우 외부의 메너페스트 파일을 읽어서 사용하게 된다.

▶메너페스트 툴(mt.exe)로 메너페스트 임베딩하기

세번째 방법은 커맨드 라인툴을 사용해서 외부에 있는 메너페스트 파일의 내용을 EXE 어셈블리에 임베딩시키는 방법이다. 만약 이미 다른 메너페스트 내용이 있다면 기존 것을 덮어쓰게 될 것이다. mt.exe라는 커맨드 라인툴을 이용하게 되는데 마이크로소프트에서 얻거나 또는 Windows Platform SDK에 함께 배포되므로 SDK를 설치했다면 바로 사용할 수 있을 것이다.

커맨드 프롬프트 창에서 다음과 같은 형식으로 작업을 해 주면 된다.

mt /manifest 메너페스트파일이름 /outputresource:실행파일이름;#1

이 명령은 실행파일의 1번 노드의 메너페스트(앞의 XN 리소스 편집기의 좌측 창에 1번이라는 번호의 메너페스트 노드가 있다)로 지정한 메너페스트 파일의 내용을 저장한다. 커맨드의 모양이 약간 어색하기는 하지만 공백을 그대로 유지해야 한다. 예를 들어 다음과 같은 모양이 될 것이다.

mt /manifest example.exemanifest /outputresource:simple.exe;#1

이제 simple.exe 파일을 실행시킬때마다 사용자는 항상 권한 상승에 대한 동의 확인창이 뜨는 것을 경험하게 된다.

그런데 메너페스트 내용을 임베딩하는 것에는 문제가 있다.

■ 메너페스트의 강제 임베딩에 대한 문제점

만약 어플리케이션을 전자 서명했다면 문제가 된다. 어플리케이션에 전자 서명을 추가하게 되면 어플리케이션이 배포될 당시의 순수했던 코드가 나중에 어떤 악의를 가진 자로부터의 수정이 일어났는지를 확인을 할 수 있게 된다. 전자 서명된 어플리케이션에 메너페스트 내용을 임베딩하게 되면 결국 배포 당시의 코드가 외부로부터 수정되는 것과 마찬가지가 된다. 결국 어플리케이션을 실행하게 되면 Vista에서는 불평을 늘어놓고 어플리케이션은 실행되지 않게 된다.