Wins blog

글로벌 정보보안 파트너! Global Security  No.1 윈스는 국가대표 정보보안 기업에서 글로벌 강소기업으로 도약합니다.

보안 정보

앞 내용 보기 다음 내용 보기
취약점 정보GNU Bash Command 실행 취약점
작성일 2014-12-23 조회 2716
1. 개요
 
GNU Bash는 Bourne shell을 교체하는 Unix shell로 Linux와 Mac OS X 시스템의 기본 Shell로 널리 배포되고 있다.
2014년 9월 24일, Stephane Chazelas에 의해 발견된 취약점은 Bash Shell이 환경변수를 처리하는 과정에서 해당 변수의 종료 시점을 인식하지 못하여 시스템의 보안을 우회하여 임의의 코드가 삽입/실행될 수 있다.
취약한 버전을 이용하고 있는 사용자의 경우 최신 버전으로 업데이트하여 공격을 예방할 수 있도록 하는 것을 권장한다.
 
 
2. 취약점 정보
구분
버전
취약버전
GNU Bash 4.3 이하버전
공격영향
임의의코드실행
CVE
CVE-2014-6271, CVE-2014-7169
 
 
 
3. 공격 원리
 
GNU Bash Shell은 프로세스 환경을 통해 다른 셀 인스턴스에 환경변수와 함수를 선언하는 기능을 제공한다.
<그림 1>  Bash Shell을 통한 함수 선언
 
함수는 “() {“ 문자열을 통해 선언하나, 환경변수의 선언과정에서 variable.c과 evalstring.c 를 확인해 보면 함수 선언 이후 내용이 함수의 정의로 보고, 나머지 입력 값에 대해서 함수 선언문인지 여부에 대한 검증이 없다.
Void
initialize_shell_variables (env, privmode)
char **env;
...
/* If exported function, define it now. Don't import functions from
the environment in privileged mode. */
"() {" 발생시 정의된 Export 된 함수 실행
if (privmode == 0 && read_but_dont_execute == 0 && STREQN ("() {", string, 4))
{
string_length = strlen (string);
temp_string = (char *)xmalloc (3 + string_length + char_index);
strcpy (temp_string, name);
temp_string[char_index] = ' ';
strcpy (temp_string + char_index + 1, string);
if (posixly_correct == 0 || legal_identifier (name))
String의 나머지는 함수정의 부분으로 가정하고 전달 후 실행
parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST);
<그림 2> variables.c의 입력 값 전달 부분
 
if (parser_expanding_alias ())
    /* push current shell_input_line */
    parser_save_alias ();
 ~생략~
  with_input_from_string (string, from_file);
 while (*(bash_input.location.string))
    {
입력 문자열을 끝까지 실행
<그림 3> evalstring.c 입력 값 실행 부분
 
이로 인하여 환경 변수에 다음의 형태로 임의의 명령어가 삽입 된다면 이를 모두 함수선언으로 인식하여 실행하게 된다.
정상 선언
[환경변수]=’() { return;};’
비정상 선어
[환경변수]=’() { return;}; [삽입된 명령]
 
<그림 4> 취약점을 이용한 환경 변수 선언
 
4. 공격 과정 분석
 
1)   공격 가능 시나리오
해당 취약점을 통해 환경 변수 선언과 관련하여 임의의 명령어가 삽입/실행 가능함을 확인하였다.
현재 알려진 공격 시나리오는 아래의 4가지 경우가 있다.
 
-      OpenSSH의 sshd의 ForceCommand 기능을 우회하는데 사용. 해당 경우는 사용자 계정을 알아야 한다는 제한사항 존재
-      Apache 웹 서버가 mod_cgi, mod_cgid 모듈을 사용하는 경우, CGI 스크립트를 이용하여 bash 명령어를 실행하거나, 서브쉘(subshell) 획득
-      DHCP 클라이언트가 악의적인 DHCP 서버로부터 획득한 값을 쉘 스크립트로 실행할 수 있음. 이 명령어는 루트 권한으로 실행
-      그 외에 권한을 가지는 데몬에서 쉘 스크립트를 실행할 수 있는 경우 이 취약점을 이용하여 데몬의 권한으로 임의의 명령을 실행
 
 
2)   공격 구현
해당 취약점이 발표된 이후 가장 많이 발생한 웹서버를 대상으로 한 공격을 구현했다.
 
<테스트 환경>
OS
CentOS 6.2
Bash
4.1.2
Web Server
Apache 2.2.15
 
※    해당 취약점을 활용하려면 bash로 짜여진 CGI 페이지가 존재해야 한다.
 
<그림 5> 취약점을 이용한 명령어 실행
 
추가적으로 URI Path 및 임의 HTTP 헤더 옵션을 통한 공격을 시현한 결과 임의의 명령어를 실행할 수 있었다.


 
 
<그림 6> URI Path를 통한 명령어 실행
 
<그림 7> 임의의 HTTP 헤더 옵션을 통한 명령어 실행
 
5. 대응방안
 
본 취약점은 환경변수 처리시 입력값에 대한 검증을 하지 못해 발생되는 취약점으로 패치된 버전이 릴리즈 되었으며, 패치된 버전에서는 함수 정의부에 대한 내용을 검증하면서 parse_and_execute()를 호출시 명령어 실행을 1회로 제한한다.
 
builtins/common.h    
 /* Flags for describe_command, shared between type.def and command.def */
 #define SEVAL_FUNCDEF      0x080             /* only allow function definitions */
 #define SEVAL_ONECMD      0x100             /* only allow a single command */
 #define CDESC_ALL            0x001   /* type -a */
 #define CDESC_SHORTDESC                    0x002   /* command -V */
builtins/evalstring.c
 struct fd_bitmap *bitmap;
 if ((flags & SEVAL_FUNCDEF) && command->type != cm_function_def)
~ 생략 ~
if (flags & SEVAL_ONECMD)
break;
}
}
builtins /variables.c
/* Don't import function names that are invalid identifiers from the
   environment, though we still allow them to be defined as shell
   variables. */
if (legal_identifier (name))
parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST|SEVAL_FUNCDEF|SEVAL_ONECMD);
명령실행 제한
<그림 8> 패치 버전의 입력 검증 및 명령어 실행 제한 부분
 
<관련 패치 정보>
 
취약점을 완화하기 위해서는 추가 확인할 점은 CGI 서비스의 사용유무를 확인하여, 해당 서비스 미사용 시에는 서비스를 중지하거나 CGI를 삭제해야 한다.
 
6. 스나이퍼 탐지 및 방어
 
Sniper 제품군에서는 해당 공격을 탐지 및 차단하기 위해 <그림 7>과 같이 시그니처 업데이트가 완료된 상태이다.
 
<그림 9> 스나이퍼 탐지
 
6. 참고 자료
 
       SecureCAST
 
          GNU Operating System
 
Common Vulnerabilities and Exposures
첨부파일 첨부파일이 없습니다.
태그