internet

[알림판목록 I] [알림판목록 II] [글목록][이 전][다 음]
From   : Liszt (장 진 웅)
Date   : Thu Aug 20 17:29:54 1992
Subject: Access Control Mechanisms of X Window System

Subject: Access Control Mechanism in X-Window System
Date: Aug 19, 1992
Author: Chang Jin-woong, Dept. of Computer Science, KAIST


                 ACCESS CONTROL MECHANISMS IN X-WINDOW SYSTEM


                                 Part   I

    X-Window 시스템이 클라이언트-서버 모델을 따르고 있다는 것은 누구나 알고
있을 것이다. 하지만 X-Window는 과연 Security에 있어서 믿을만 한가? 내가
살펴본 바에 의하면 결코 그렇지 못하다. 왜냐하면 X-Window는 현재 매우 단순한
형태의 Access Control 기능만을 갖고 있고, 그런 기능들 조차 사용하기에 매우
불편하기 때문에 일반 사용자들은 거의 그런 문제에 신경쓰지 않는 실정이다.
이것은 매우 심각한 보안상 취약점을 야기시킬 수 있다.

    어떤 X 클라이언트가 서버와 접속되면 (Xlib의 XOpenDisplay()함수에 의해
이루어짐) 그 클라이언트는 서버에 대한 모든 제어 권한을 갖게 된다.
원래 X-Window는 "Cooperating Clients"를 염두에 두고 설계되었기 때문에
클라이언트들 간의 액세스 제어같은 개념은 포함하고 있지 않다. 극단적으로
말하면 한 클라이언트가 다른 클라이언트에서 만들어 놓은 윈도우를 지워버릴
수도 있다.(Root 윈도우에서 Xlib의 XDestroySubWindows()를 실행시킨다면 화면에
있는 모든 윈도우들을 날려버릴 것이다.) 또다른 위험한 경우는 무엇이 있을까?
어떤 클라이언트가 서버에서 발생하는 모든 키보드 이벤트를 받아들이는 경우
그 클라이언트는 사용자가 두드리고 있는 키들을 모두 기록할 수도 있는 것이다.--
물론 패스워드도 포함해서 말이다.

    그렇다면 X-Window 시스템은 어떻게 이런 불법적인 클라이언트들의 공격을
막아낼 수 있을까? X를 설계한 사람들의 결론은 간단했다. 불법적인 클라이언트들이
X 서버와 접속하지 못하게 만드는 것이다. 그렇다면 X 서버는 어느 클라이언트가
제대로 된 것이고 어느 클라이언트가 불법적인 것인지 가려낼 수 있단 말인가?

    이 물음에 대한 해답은 실제로 X 서버와 클라이언트 사이에 접속이 이루어지는
과정을 설명하는 편이 훨씬 도움이 되리라 생각된다.

    클라이언트가 특정한 X 서버 "baram:0"과 접속하고자 할 때, 제일 먼저
XOpenDisplay("baram:0") 을 실행할 것이다. XOpenDisplay() 함수는 인수로 주어진
서버의 호스트명인 "baram"의 TCP Port 6000번에 접속을 시도한다.
TCP 접속이 이루어지면 서버는 Client의 IP Address를 조사하여, 자신이 갖고 있는
일단의 호스트 목록에 클라이언트의 주소가 포함되어 있으면 그 클라이언트를
무조건 자신과 접속시킨다. 즉 목록에 포함된 호스트들에서 실행된 모든
클라이언트는 그 서버와 접속가능하다.
    이러한 메카니즘은 개인용 워크스테이션을 쓰거나 그다지 보안을 필요로 하지
않는 곳에서는 쓸만 하겠으나 위에서 제시한 문제를 해결하기에는 적당한 방법이
못된다. 사용자는 이러한 Host-Based Access Control 기능을 작동하지 못하게 할
수도 있다.(xhost(1)를 참고하시오) 사용자가 XHostAccessControl() 함수를
사용하여 이 기능을 Disable시키면 그 이후로 일어나는 모든 클라이언트와의 접속은
서버에 있는 호스트 목록의 내용과 관계없이 아래에 설명한 내용을 따른다.

    접속을 시도하는 클라이언트는 서버로 몇가지 데이터를 보내야 한다. 그중의
일부가 "Authority Data"로, 사용자의 $HOME/.Xauthority 화일에 저장되어 있다.
그러면 .Xauthority 화일의 구조를 살펴보자. 화일은 2진 형식으로 되어 있으므로
"xauth"라는 프로그램을 통해서만 볼 수 있다.

baram% xauth
Using authority file /home2/sparcs/jwjang/.Xauthority
xauth> list
ara.kaist.ac.kr:0  MIT-MAGIC-COOKIE-1  6c35ca3b58b1961704ed22b370e96e0f
baram.kaist.ac.kr:0  MIT-MAGIC-COOKIE-1  3e9fecb54abbd8311697846da233f069
^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
gurum.kaist.ac.kr:0  MIT-MAGIC-COOKIE-1  b54abbd8311697846da233f069ee8f1c
beta.kaist.ac.kr/unix:0  MIT-MAGIC-COOKIE-1  2cf58afb187156d7c4ade27330a92ecf
maru.kaist.ac.kr:0  MIT-MAGIC-COOKIE-1  c9ceeffc85da0be801a6e7943d328300
cair.kaist.ac.kr:0  MIT-MAGIC-COOKIE-1  95aa9b38117677e44d021350494e6f7c
eve11:0  MIT-MAGIC-COOKIE-1  733934765a4b4f5350774a327a546b75
xauth> quit
baram%

    첫번째 컬럼의 내용은 서버의 이름이다. 그리고 두번째 컬럼에 있는 것은
세번째 컬럼에 있는 16진 데이터가 어떤 "Authorization Mechanism"을 따르고
있는지 밝히는 것이다. 위에서 '^'로 밑줄친 행을 보면 X 서버 "baram:0"가
"MIT-MAGIC-COOKIE-1"이라는 방법을 쓰고 있으며 이때 클라이언트 측에서 서버에
보내야 할 데이터가 "3e9fecb54abbd8311697846da233f069"임을 뜻하고 있다.

    즉, XOpenDisplay() 함수는 사용자의 홈 디렉토리에 있는 .Xauthority 화일을
조사하여 자신이 접속하고자 하는 서버의 이름을 가진 행을 찾아 거기에 있는
"Authorization Mechanism"의 이름과 16 바이트의 2진 데이터를 함께 전송한다.

   +-----------------+      "MIT-MAGIC-COOKIE-1"         +------------------+
   |    X Client     |"3e9fecb54abbd8311697846da233f069" |     X Server     |
   |User: jwjang@dal1|==================================>|     baram:0      |
   +-----------------+                                   +------------------+
 XOpenDisplay("baram:0")

    두가지 데이터를 받은 서버는 우선 자신이 "MIT-MAGIC-COOKIE-1"라는 메카니즘을
갖고 있는지 조사한다. 갖고 있지 않으면 당연히 접속은 이루어지지 않을 것이다.
그 다음 자신의 메카니즘에 따라 클라이언트가 보내온 2진 데이터를 조사하여
맞으면 접속이 이루어지고, 틀리면 접속이 안되는 것이다. 일종의 암호라고
볼 수도 있겠다.

    그러면 "MIT-MAGIC-COOKIE-1"이라는 메카니즘은 무엇인가? 이것은 클라이언트와
서버 간에 16바이트의 "Cookie"를 공유하는 방식으로 되어 있다. 즉, 클라이언트가
보내온 16바이트의 데이터가 서버 자신이 갖고 있는 데이터와 일치하면 접속을
허락하는 것이다. 현재 대부분의 X 서버는 이 방식을 채택하고 있다.(MIT의 서버가
이 방식을 채택하고 있기 때문이라고 말하는 편이 옳겠다.)

    또 다른 질문: 클라이언트와 서버의 "Cookie"를 일치시켜주는 역할은 누가
하나? 그 해답은 xdm(X Display Manager)이다. xdm은 사용자가 로그인할때 마다
16바이트의 난수를 만들어 사용자의 .Xauthority 화일과 서버에 똑같이 저장한다.
그러므로 xdm을 통해 로그인한 사용자는 로그인한 호스트를 벗어나지 않는 한
클라이언트를 실행시킬 때 아무런 문제도 없을 것이다. 그러나 만약 그 사용자가
다른 호스트로 Remote 로그인을 하고 그 호스트에서 "setenv DISPLAY baram:0"
을 한다음 클라이언트를 실행시키면 과연 접속이 이루어질까?

    대답은 물론 "아니오"다. xdm이 할일이 없어서 다른 호스트에 있는 .Xauthority
화일까지 다 고쳐주는 것은 아니기 때문이다. 만약 Remote 호스트에서 기어코
서버와 접속하고 싶으면 처음에 xdm으로 로그인한 호스트에서 .Xauthority화일을
복사해 오는 수 밖에 없다.

    MIT-MAGIC-COOKIE-1과 같은 "공유되는 키" 방식은 꽤 쓸모가 있다. 그러나
Ethernet과 같은 Broadcast Bus방식의 네트웍을 쓰는 곳에는 또 문제가 생길 수
있다. 클라이언트가 서버로 "Cookie"를 보낼 때 암호화시키지 않고 그대로
보내기 때문에 다른 호스트에서 "Cookie"가 담긴 패킷을 훔쳐 볼 수가 있는 것이다.
(실제로 etherfind나 tcpdump같은 프로그램으로 가능함) 훔쳐낸 "Cookie"를 쓰면
어떤 클라이언트도 서버에 접속할 수 있을 것이다.

    MIT는 X-Window 시스템의 이러한 취약점을 보완하기위해 "XDM-AUTHORIZATION-1"
이라는 새로운 메카니즘을 개발하였다. 이 방법은 .Xauthority화일에 있는
데이터를 암호화시켜 보내므로 다른 호스트가 훔쳐보는 것을 걱정할 필요가 없다.
그러나 애석하게도 MIT는 암호화 알고리즘으로 DES(Data Encryption Standard)를
사용하였기 때문에 미국 밖으로 배포되는 X 패키지에는 DES와 관련된 부분들이
모두 빠져있다. (그러나 여러 나라에서 Public Domain으로 DES를 많이 만들어
놓았다. 이것들을 활용하면 "XDM-AUTHORIZATION-1"을 쓸 수 있을 것이다. 본인이
cair.kaist.ac.kr에서 anonymous ftp service를 관리하고 있었을 때 호주에서
만들어진 DES관련 소스들을 모아두었는데 지금은 cair가 고장나 있으니 다시
구하는 수 밖에 없을 것 같다.)

    지금까지는 X-Window에서 클라이언트와 서버사이의 접속 제어 방식을
알아보았다. 그런데 xdm의 경우는 어떤가? xdm도 다른 클라이언트와 다를 것이
없다고 생각하면 xdm도 서버와 접속할 때 똑같은 방식을 쓰는가? 물론 그렇지 않다.
xdm은 사용자의 로그인 네임과 암호를 받아들이므로 훨씬 고도의 암호화 기법을
써야 할 것이다. 게다가 XDMCP(X Display Manager Control Protocol)이라는
특별한 프로토콜까지 사용한다. 자세한 내용은 Part II에서!!

<< Bibliography >>

Manual Pages: X(1), Xserver(1), Xauth(1), xauth(1), xhost(1), Xsecurity(1),
 xdm(1).
Documents from X Consortium: X11R5 Release Notes, XDMCP Specification 1.0
Printed Manuals:(authors are not credited)
X Window System User's Guide., O'Riley & Associates.
X Window System - Complete Reference to Xlib, Protocol, ICCCM, XLFD., Digital
Press.
UNIX Network Programming Guide., Prentice-Hall.
[알림판목록 I] [알림판목록 II] [글 목록][이 전][다 음]
키 즈 는 열 린 사 람 들 의 모 임 입 니 다.