유닉스/리눅스 운영체제는 태어난지 수십년이 지난 지금(2014)도 그 자체로 취약성 덩어리라 해도 과언이 아니다. 다만 네트워크기반의 다른 보안솔루션들의 집중적인 보호(침입차단)를 받고 있고 자체적으로는 사용자인증(로그인)과 기본적인 사용자간의 권한분리(계정을 통한 분리)를 통해 최소한의 보안을 유지하고 있는 것이다. 하지만 말 그대로 “최소한”의 보안이다.
유닉스/리눅스 운영체제를 공부하다 보면 수도 없이 많은 보안 취약성을 발견하게 된다. 그 취약성은 개방성을 기반으로 개발된 운영체제이기 때문이기도 하지만 사실…별다른 보안개념을 적용하지 않고 개발된 운영체제이기 때문이기도 한다.
그중에서 오늘 소개할 것은 심볼릭링크 취약성과 쉘의 취약성이다. (심볼릭링크는 윈도의 단축아이콘과 유사하다.)
이따금씩 서버보안 S/W의 시연이나 BMT를 진행하다보면 일부 취약성 공격의 방어에 대한 시연을 요청하는 경우가 있다. 대부분 웹쉘 방어 혹은 웹 소스 위변조 차단에 대한 시연을 진행하는데 이번엔 심볼릭링크 취약성까지 시연해야 하는 경우가 생겼다. 사실… 버퍼오버플로나 포맷스트링 등은 이론적으로만 이해하고 있고 실습(?)을 해보지는 않았다. 사실 해당 취약성을 내포한 애플리케이션을 코딩(C로)하고 테스트하는 과정은 썩 단순하지는 않다. 이따금씩 하는 코딩 실력으론 어려운게 사실이다.
하지만 레이스컨디션은 너무도 쉽고 단순한 쉘스크립트로도 실습이 가능하다. 아주 오래전 한참 코딩에 빠져있을 때 원조 모의해킹 실습사이트(이름은 생각나지 않음)에 들어가 모의해킹을 통해 레벨을 올라가는 도전을 해본적이 있다. 당시 15레벨인가가 명예의전당이었던것 같은데 당시에 8레벨인가가 레이스컨디션 공격을 해야하는 문제였었다. 난 8레벨 획득을 끝으로 더이상 도전하지 않았다. 9레벨에 가려면 인라인어셈블리까지 해야했기 때문이었다. (어셈블리는 인간의 언어가 아니라고 난 생각한다. ^^)
이제 본론으로 넘어가자.
1. 심볼릭링크 취약성을 가진 쉘스크립트
심볼릭링크 취약성은 다양한 프로그램에서 갖고 있다. 특히 임시파일을 생성하고 생성한 임시파일에 쓰기를 하거나 실행을 하는 경우 발생할 수 있다. 특히 root계정으로 실행되면서 임시파일을 생성하고 그 임시파일이 다른 작업을 수행하는 경우 심각한 2차 취약성을 만들거나 시스템에 장애 혹은 정보유출 등으로 이어질 수 있다.
위의 vulrace.sh 는 무한루프를 돌면서 /tmp 디렉토리에 1.sh라는 파일을 만들고 메시지 한줄을 화면에 출력하는 echo문을 저장한 뒤 그 생성한 파일(1.sh)에 실행퍼미션을 부여하고 그 파일을 실행한다.(설명이 복잡한가?) 그리고 실행이 종료되면 임시파일(1.sh)을 삭제한다.
이 과정에서 취약성은 바로 /tmp/1.sh를 삭제하고 다음번 루프에서 echo명령으로 임시파일을 생성하고 실행하는 사이에서 발생한다. 임시파일인 1.sh를 생성하기 전에 누군가가 root 권한으로 실행되기를 바라는 파일로 1.sh라는 심볼릭링크를 먼저 생성하면 이 프로그램(vulrace.sh)은 1.sh라는 정상 임시파일을 만들지 못하고 심볼릭링크인 1.sh에 echo문을 실행하게 된다. 즉 1.sh가 가리키고 있는 엉뚱한 파일에 echo문이 추가되고 실행되는 것이다. 이 엉뚱한 파일이 무엇이냐에 따라 공격의 내용이 달라지게 된다. 그 엉뚱한 파일은 root 권한으로 실행되게 된다. vulrace.sh가 root 권한으로 실행되었으므로…
위의 예제에서는 해당 취약성 공격 성공률을 높이기 위해 sleep 1을 넣어 공격이 쉽게 성공하도록 하였다.
2. 엉뚱한 파일 (쉘카피백도어)
이제 1.sh로 심볼릭링크가 걸릴 스크립트, 즉 공격자가 root권한으로 실행하고자 하는 “엉뚱한 파일”을 만들 차례다. 이 엉뚱한 파일은 쉘카피백도어를 만드는 스크립트를 예를 든다. 따로 설명은 안하겠다. 악용될 경우 심각한 문제를 유발할 수 있기 때문이며… 이 예제를 악용하여 발생하는 문제는 해당 사용자에게 있음을 분명히 밝혀둔다. 하지만 이 정도의 예제는 인터넷을 통해 얼마든지 접할 수 있고 매우 고전적인 방법이지만 최신 운영체제에서도 적용 가능한 기법이다.
이 스크립트가 root 계정에 의해 실행될 경우 /tmp/ 디렉토리에 backdoor라는 루트쉘이 생성된다. 이후 일반계정에서 이 생성된 /tmp/backdoor를 실행할 경우 root 권한을 획득하게 된다.
vulrace.sh가 실행하는 1.sh로 attack.sh 를 심볼릭링크를 걸면된다. (방법은 뒤에서~~)
3. 취약한 스크립트 실행과 공격 성공
심볼릭링크 취약성을 가진 vulrace.sh를 root 계정에서 실행하면 vulrace.sh가 생성하는 /tmp/1.sh에 의해 심볼릭링크 취약성이 있다는 메시지가 출력된다. 이 메시지를 출력하는 것은 정상적인 /tmp/1.sh 이다.
중간의 Attack Success…!! 메시지는 엉뚱한 파일(attack.sh)를 가리키는 /tmp/1.sh 라는 심볼릭링크가 실행되었을 때 attack.sh가 실행되어 출력되는 메시지다. 해커가 /tmp 디렉토리에 1.sh라는 심볼릭링크를 생성하고 vulrace.sh가 해당 심볼릭링크를 실행한 것이다.
4. 공격과 결과
공격은 아래 화면의 ln 명령에 의해 이루어진다. 즉 해커가 root 권한으로 실행하고자 하는 내용을 담은 스크립트를 /tmp/1.sh 로 심볼릭링크를 생성하는 것이다.
그리고 공격이 성공하면 attack.sh가 하고자 했던 /tmp/backdoor 가 생성된다.
root 소유자이고 소유자의 setuid가 생성되어 있다.
일반계정인 taeho에서 /tmp/backdoor를 실행하면 root 권한을 얻을 수 있다.
p.s 만약 tmp 디렉토리에서 chown 명령이 에러가 발생한다면 tmp 디렉토리에 sticky bit 가 설정되어 있기 때문이다. 샘플 소스의 디렉토리를 /tmp가 아닌 다른 경로로 설정한 뒤 테스트하면 된다.
5. 레이스컨디션 공격 방어 방법
이 심볼릭링크가 갖는 취약성 공격을 방어하기 위해서는 서버 내에서 실행되는 모든 스크립트와 실행파일에 대해 하나하나 모두 검증해야 한다.
1. 임시파일을 생성하고 실행하거나 수정하는 어떤 프로그램들이나 쉘스크립트가 있는가?
2. 만약 있다면…(100% 존재하며 모두 파악하는 것은 거의 불가능함) 임시파일을 생성하기 전에 생성할 임시파일이 이미 존재하는지 확인하고 존재한다면 프로그램을 중단하도록 소스코드 수정 –> 사실상 불가능함
3. 심볼릭링크를 사용하지 못하도록 함. (역시 사실상 불가능함)
그렇다면 방법이 없는가?
방법은 있다.
바로 RedCastle SecureOS를 설치하면 된다. RedCastle SecureOS는 Race Condition 공격을 100% 차단 할 수 있다. RedCastle SecureOS는 운영체제의 커널수준에서 심볼릭링크의 생성을 모니터링하여 root계정에서 실행된 명령어 혹은 대몬프로세스가 일반소유자의 파일로 연결되는 심볼릭링크를 실행하는 것을 차단해준다.
이러한 보호는 SecureOS의 핵심보듈인 커널수준에서 구현된 참조모니터에 의해 구현되기 때문에 예외없이 모든 심볼릭링크 취약성 공격에 대해 방어가 가능하다.