티스토리 뷰

발생일: 2013.02.17

문제:
얼마 전 맥의 커맨드라인 svn을 업데이트 했다.

맥의 패키지 매니저 중의 하나인 Homebrew를 이용해서 인스톨했고,
기존 버전은 1.6.18, 새로 받은 버전은 1.7.8이었다.

헌데, 업데이트 받은 후에도 svn이 기존 버전을 그대로 유지하고 있는 거다.

  $ svn --version
  svn, version 1.6.18 ...

혹시나 해서 type을 확인해보니, 기존 경로의 바이너리가 호출되고 있었다.

  $ type svn
  svn hashed (/usr/bin/svn)

  (type 커맨드로 파일의 타입을 확인할 수 있고, 실행 파일일 경우 경로를 알 수 있다)


새로 받은 svn은 /usr/local/bin 에 넣어뒀지만,
PATH 변수에서 /usr/bin 이 /usr/local/bin 보다 먼저 선언되어 있기 때문이었다.

PATH 변수에서 실행 파일을 찾을 때에는,
중복 여부에 관계 없이 먼저 선언되어 있는 경로의 것을 사용한다.

예를 들어, oops 라는 커맨드를 실행하려고 하고,
각 커맨드가 /foo/bin/oops, /bar/bin/oops 디렉토리에 있다고 가정해보자.

PATH 변수에 /foo/bin:/bar/bin:/foo/bin 와 같이 선언되어 있다면,
맨 앞에 정의된 /foo/bin 에서 oops를 찾아 실행한다.


그러고보니, 왜 /usr/bin 이 사용자 정의인 /usr/local/bin 보다 우선순위를 갖도록 한 걸까?

PATH 초기화 정보가 정의되어 있는 /etc/paths 파일을 임의로 수정해서,
/usr/local/bin 이 우선순위를 갖도록 해도 문제가 없을까?



해결책:

/etc/paths 는 시스템의 초기 PATH를 정의해둔 파일이고,
기본적으로 아래와 같이 설정되어 있다.

  /usr/bin
  /bin
  /usr/sbin
  /sbin
  /usr/local/bin

순서대로 PATH 변수에 초기화되기 때문에, 
위 문제를 해결하려면 맨 마지막의 /usr/local/bin 을 맨 앞으로 옮기면 되긴 하다.


하지만, 이건 보안 문제를 야기할 수 있기 때문에 좋은 생각이 아니다.

먼저, 초기 PATH 변수 내의 각 경로가 의미하는 바는 아래와 같다.

  /bin : 싱글 유저 모드에서 필요하고, 모든 유저가 사용하는 필수 커맨드 바이너리 (cat, ls, cp 등)
  /sbin : 시스템에서 사용하는 필수 바이너리 (init, ip, mount 등)
  /usr/bin : 싱글 유저 모드에 필요하지 않고, 모든 유저가 사용하는 바이너리
  /usr/sbin : 필수가 아닌 시스템 바이너리
  /usr/local/bin : 특정 사용자를 위한 커맨드 바이너리


만약, /usr/local/bin 파일이 우선순위를 가지고 있고,
악성코드를 가진 파일이 /usr/bin의 바이너리와 동일한 이름으로 bin 파일에 들어가게 되면 보안 상 심각한 문제를 발생할 수 있다.


이 위험은 간단하게 테스트해 볼 수 있다.
여기서는, ssh 파일을 덮어써보는 방식으로 설명하려고 한다.

  1. /usr/local/bin 에 ssh 파일을 만들고, 실행 권한을 준다.
    $ echo "echo EVIL" > ssh; chmod +x ssh;
  2. 커맨드 라인에서 ssh 명령을 실행해본다.
    $ ssh
    EVIL

1번 과정에서 사용자 디렉토리이기 때문에 파일을 생성할 때에도 별도의 권한이 필요하지 않다.
2번 과정에서, ssh 커맨드가 /usr/bin에 존재하긴 하지만 /usr/local/bin 이 실행 우선 순위가 높기 때문에,
우리가 생성한 (악성 코드가 포함된 거라고 가정한) ssh 커맨드가 실행된 것이다.


문제에서 언급했던 svn 커맨드가,
/usr/local/bin 폴더의 svn으로 실행될 수 있도록 하는 방법에는 여러 가지가 있다.

  1. 위에 언급한 것처럼 직접 /etc/paths의 순서를 변경한다.
      --> 보안 상 위험하다.

  2. .bash_profile에서 /usr/local/bin 을 PATH의 맨 앞으로 설정
      $ export PATH=/usr/local/bin:$PATH
      --> 마찬가지로 보안 상 위험하다.

  3. /usr/bin의 svn 파일을 삭제하고 대체한다.
      --> 나쁘지 않으나, PC를 교체할 때 잊을 수 있고, 다른 사용자에게 영향을 끼칠 수 있다.

  4. /usr/bin 에 /usr/local/bin/svn 으로의 심링크를 만든다.
      --> 다른 사용자가 있을 경우 문제가 된다.

  5. 호출할 때 항상 경로를 붙인다.
      $ /usr/local/bin/svn ...
      --> 귀찮다...

  6. .bash_profile에 앨리어스를 설정한다.
      $ alias svn="/usr/local/bin/svn"
      --> 명확하고 가장 안전하다.


같은 문제로 구글링 해보니 그냥 사용해도 별 문제 없을 거라는 의견도 있고,
실제로도 악성 코드에 감염될 일이 얼마나 있겠냐마는...

/usr/bin 디렉토리에 make나 autoconf 같은 명령어도 포함되어 있고,
충분히 악성코드를 심을 수 있다는 걸 생각해보면 꽤나 위험한 설정 같기도 하다.


좀 귀찮아도, 앨리어스를 설정해서 쓰자.









반응형
댓글
공지사항