[여기보기]는 “여기서 보안의 기본을 챙기고 가자”의 약자로, 개발 과정에서 꼭 최소한으로 챙기면 좋을 보안 기초 설정을 앞으로 하나씩 공유할 예정입니다. 기초 내용이 주를 이루겠지만, 혹시라도 빼먹고 계신 것이 없는지 가끔 한 번씩 둘러봐 주세요
안녕하세요, 넷마블 보안실 보안개발팀 이대성입니다.
단순히 배터리를 충전하려고 PC에 스마트폰을 연결했을 뿐인데, 외장 스토리지나 기타 미디어 기기 등을 인식해서 연결 여부 메시지가 뜨는 상황을 겪어보셨나요? 연결을 의도하지 않았지만, PC가 스마트폰 장착을 자동 인식했기 때문에 뜨는 메시지입니다.
일회성 사용을 위해 연결한 장비의 장치 드라이버와 프로그램을 설치한 후 지우지 않고 그대로 뒀다가, 어느 날 그 프로그램 업데이트 알림 메시지를 본 적도 있으신가요? 프로그램을 설치했던 과정에서 얻은 몇몇 권한을 활용해, 자동으로 업데이트 버전을 확인하는 프로세스를 거쳐서 뜬 메시지입니다.
안심할 수 있거나 안전한 장비 또는 프로그램이라면, 위 상황으로 인한 위협 상황이 발생할 확률은 매우 낮습니다. 하지만 만약 추가할 장비가 볼륨 스토리지(Volume Storage) 이외는 특별히 운영 도중에 붙일 장비가 없는 리눅스 서버라면 어떨까요?
존재하지 않는 장치(Device) 파일 제거
리눅스에서 ‘/dev’에는 장치 드라이버나 설정을 위한 다양한 정보가 들어있습니다. (여기에 장치 관련 모든 파일이 있는 것은 아닙니다.) 파일 형태도 일반 파일부터 심볼릭 링크(Symbolic Link), 디렉터리, 블록 장치 파일(Block Device File), 문자 장치 파일(Character Device File)까지 다양합니다. 시스템 기본으로 생성됐거나, 과거에 연결했던 당시에 자동으로 생성됐거나, 필요로 인해 수동으로 생성한 이유로 ‘/dev’ 디렉터리에 모여 있습니다.
라즈베리파이나 PC에서 리눅스를 기본 OS로 사용할 때에는 새 장치를 연결하고 해제하는 일이 자주 일어나므로, ‘/dev’ 디렉터리에 장치 관련 파일이 계속 늘어납니다. 다행히 동일한 장치라면 파일을 새로 만들지 않고, 기존 파일을 사용합니다.
하지만, 데이터 센터나 서버실을 별도로 준비해서 리눅스 서버를 사용하는 경우에는 수시로 직접 장치를 추가해 연결하고 해제하는 일이 드물게 일어납니다. 드물게 일어나기 때문에 ‘/dev’ 디렉터리에 장치 관련 파일이 계속 늘어날 일이 거의 없습니다. 그래서 다른 장치를 연결해서 장치 관련 파일이 계속 생성된 영향으로 발생하는 오류는 거의 발생하지 않습니다. 하지만 서버가 원격지에 있으므로 실제로 현장에서 누가 어떤 장치를 새로 연결했는지 직접 확인하기가 어렵습니다.
공격자는 이 특징과 패턴을 활용해 루트킷(rootkit)을 서버 관리자가 크게 신경 쓰지 않는 ‘/dev’ 디렉터리에 위장시켜 넣습니다. 서버 관리자가 루트킷을 장치 관련 파일인 것으로 착각하도록, 넘버링을 활용하거나 비슷한 문자열로 파일을 추가합니다. ‘tty0’를 ‘ttyo’로 쓰거나, ‘tty37’까지만 있는 서버에 ‘tty38’을 임의로 생성해서 넣거나 하는 거죠.
일반 파일(-), 심볼릭 링크(l), 디렉터리(d), 블록 장치 파일(b), 문자 장치 파일(c) 등 파일 형태를 구분해서 볼 수 있다고 하더라도, 이미 루트킷에 노출됐다면 동종 형태로 악성 파일을 숨겨놓는 것은 그리 어렵지 않을 것입니다.
조치방안
파일 점검
존재하지 않는 장치 관련 파일이 ‘/dev’ 디렉터리에 존재하는 경우, 아래 방법에 따라 제거하는 것이 좋습니다. 일반적인 경우 영향이 거의 없으므로, 당장 사용하지 않는 장치도 같이 제거해도 괜찮습니다. 어차피 계획에 맞춰 다시 사용할 때, 장치 관련 파일이 자동 생성되거나 그때 추가하면 되니까요.
# /dev 디렉터리 파일 점검
$ find /dev -type f -exec ls -l {} \;
#2 사용하지 않는 장치일 경우 삭제
$ rm [파일]
$ find . -type f -name [파일 이름] -exec rm {} \;
마스터 OS 이미지 관리 체계 구축
번거롭고 귀찮겠지만, 서버 관리자가 사용 중인 장치를 대조군 서버나 체크섬을 정확하게 하나씩 비교하는 방법도 있습니다. 마스터 OS로 동일한 가상 서버 환경을 세팅하고 서로 비교하는 에이전트나 스크립트를 생성해서 주기적으로 확인한다면, 잠복해있는 악성 파일도 미리 찾을 수 있습니다.
automountd 제거
automountd는 클라이언트가 서버에 파일 시스템을 자동으로 마운트(autofs)하고, 일정 시간 사용하지 않으면 마운트를 해제하는 서비스용 데몬입니다.
- automountd – automountd(1m) linux man page
automountd 자체에는 위협 사항이 없다고 볼 수 있습니다. 다만, 파일 시스템을 마운트할 때 루트 권한을 획득하는 옵션을 부여할 수 있다는 점에서 위협 사항이 발생합니다. 악의적 행위를 하는 스크립트나 파일이 들어있는 저장 장치가 연결과 동시에 루트 권한을 획득한다면, 서버 시스템 전체를 엉망으로 만들지도 모릅니다.
또한, automountd를 활용해 RPC(Remote Procedure Call) 명령을 보낼 수 있다는 점도 큰 취약점입니다. RPC를 호출하는 취약점은 automountd 이외에도 몇몇 서비스가 더 있습니다만, 다른 기회에 다른 글에서 소개해 드리겠습니다.
- RPC(Remote Procedure Call, 원격 프로시저 호출):
원격 제어를 위한 별도의 프로그래밍 없이 다른 주소 공간에서 함수나 프로시저를 실행하는 프로세스 간 프로토콜
조치 방안
이런 이유로 automountd 서비스가 비활성화 상태가 맞는지 확인하고, 재부팅 시에도 서비스가 활성화되지 않도록 자동 실행 스크립트도 함께 확인해야 합니다. (autofs 데몬도 같이 확인하는 것이 좋습니다.)
#1 automountd 서비스 데몬 중지
$ ps -ef | grep automount
$ ps -ef | grep autofs
$ kill -9 [PID]
#2 시동 스크립트 위치 확인 및 삭제
$ ls -al /etc/rc*.d/* | grep automount
$ ls -al /etc/rc*.d/* | grep autofs
여담으로, 간혹 위 예시 이미지처럼 나온 결과를 automountd 서비스가 떠 있는 줄 알고 프로세스 킬을 반복하시는 분이 계십니다. 당연히 킬하고 다시 조회하면 또 반복해서 떠 있죠. automountd 서비스를 찾기 위해 실행한 그 자체 프로세스라서 그렇습니다. 위 예시 이미지는 automountd 서비스가 실행 중이지 않은 결과입니다. 동작 중인 프로세스 결과 화면이 궁금하시다면 nginx 같은 서비스를 조회해보시면 확실한 차이를 보실 수 있습니다.
장치 인식은 끝이 아닌 시작
서버 침투 대부분 단순한 1차 침투로 끝나지 않습니다. 빈틈은 찾아 들어가는 구멍이 될 뿐, 그 구멍으로 들어간 후에는 다시 또 새로운 침투 행위를 시작합니다. 1차 침투로 시작해서 N차 침투까지 끝을 향해 가는 거죠. 하물며 그조차도 사람이 직접 서버 하나하나에 대응하는 것이 아닌, 자동화된 스크립트 봇이 훑고 갑니다.
바늘구멍이 블랙홀로 바뀌는 건 한순간입니다. 오늘도 무탈한 리눅스 서버 라이프가 되시길 기원합니다.