0x02 Study :)/Pwnable

[pwnable.kr][Toddler] shellshock 문제풀이

eli_ez3r 2018. 8. 18. 10:38


shellshock

shellshock@ubuntu:~$ ls -l
total 960
-r-xr-xr-x 1 root shellshock     959120 Oct 12  2014 bash
-r--r----- 1 root shellshock_pwn     47 Oct 12  2014 flag
-r-xr-sr-x 1 root shellshock_pwn   8547 Oct 12  2014 shellshock
-r--r--r-- 1 root root              188 Oct 12  2014 shellshock.c

ls로 해서 보면 shellshock과 bash가 존재한다.

shellshock.c를 살펴보자.

 

#include <stdio.h>
int main(){
	setresuid(getegid(), getegid(), getegid());
	setresgid(getegid(), getegid(), getegid());
	system("/home/shellshock/bash -c 'echo shock_me'");
	return 0;
}

bash -c 를 이용하여 'echo shock_me'를 실행한다. (-c : 명령어 실행)

문제 이름도 shellshock이고 하니 Bash shellshock 취약점이 생각났다.

 

간략하게 CVE-2014-6271(Bash Shellshock) 취약점은 Linux/Unix System에서 사용되는 shell인 Bash shell에 존재하는 취약점으로 대략 40년 이상 존재해온 취약점이라고 한다.

Bash Shellshock취약점은 특정 버전에서만 취약했던 HeartBleed취약점(CVE-2014-0160)보다 더욱 위험한 공격으로 분류된다. 실제 위험도 수치도 10점 만점에 10점으로 분류 되었다.

 

Bash Shellshock 취약점은 최초 CVE-2014-6271로 CVE 코드를 부여 받은 후, patch, 취약점 탐지, patch 등을 반복 하면서 여러개의 CVE가 존재한다. (CVE-2014-7169, CVE-2014-7186, CVE-2014-7187, CVE-2014-6277)

 

해당 취약점을 이해하기 위해서는 Bash Shell에서 환경변수를 설정하는 방법, Bash 프로그램이 동작하는 구조를 이해해야 한다.

 

이해 하기에 앞서 이번 문제를 푸는 과정을 먼저 보고 어떻게 가능한지 하나씩 살펴보자.




해당 문제를 보면, shellshock을 실행하면 내부에서 shellshock디렉터리 안에 bash를 실행한다.

그리고 bash가 실행되면서 사용자가 설정한 임의의 함수(환경변수로 등록한)가 실행된다.



Bash 환경변수 세팅

Bash shell은 특정 프로그램을 사용자가 실행 할 수 있도록 사람과 OS사이에 인터페이스 역할을 해준다.

환경 변수는 특정 프로그램을 실행 할 때 그 프로그램이 실행 되는데 영향을 줄 수있는 변수들이다.

해당 취약점은 Bash에 환경변수에 있다.

bash에서는 환경변수로 함수를 선언하는 것이 가능하다.



'{'와 'echo'사이에는 한 칸 이상의 공백이 있어야 한다. 

 export를 통해 변수 또는 함수를 export해주면 현재 bash의 subprocess에서도 해당 변수 또는 함수를 사용 가능하게 된다. 
보통은 export하지 않으면 subprocess bash에서는 전에 선언한 함수나 변수를 사용할 수 없다.

👆함수를 export하지 않는 경우 subprocess로 bash를 실행 했을 때 eunice 함수가 실행되지 않는다. 👆


 

👆함수를 export로 정의한 후 subprocess에서 실행 했을 때, eunice함수가 실행된다.👆


위에서 중요한 부분이 있다.

 

기존 함수를 정의 할 때는 eunice() { .... } 로 정의 하였는데, export 할 때는 조금 다르다.

export한 eunice는 사실 함수가 아니라 변수이다. eunice='() { .... }' 로 선언 하였는데 subprocess가 실행되면 함수로 인식한다는 점이다. CVE-2014-6271 취약점은 ()로 시작하는 변수가 subshell이 실행되면 { ... } 부분이 함수로 인식되는데 그 이후에 나오는 어떤 커맨드가 실행된다는 취약점이다.


예를 들어 다음과 같다.


👆bash만 실행 시켰을 뿐인데 pwd가 같이 실행되었다.👆



Bash 동작 원리

왜 bash의 subprocess를 실행 시키면 위의 조작된 명령어가 실행되는 것일까?

그 이유는 Bash의 동작을 살펴보면 알 수 있다.


1. Bash실행

2. ✔︎Bash 환경변수 초기화

3. Bash Shell Prompt 출력

4. 명령어 기다림

5. (명령어를 수행 할 경우) 명령어를 문자열로 저장하여 해당 문자열 parsing 수행

6. parsing 된 구조체를 이용하여 명령어 수행


Bash 동작 과정에서 취약점과 연관된 중요한 부분은 'Bash 환경변수 초기화' 부분이다. Bash를 실행한 후 shell prompt를 출력하기 전에 반드시 환경변수를 초기화 해준다. 이 과정에서 취약점이 존재하여 뒤의 명령어(pwd)가 실행되는 것이다.


‼️여기서 생각해야 할 점은, shell을 획득한 경우에서만 해당 취약점공격이 가능할까? 라는 점이다. 결론부터 말하면 Shell을 획득하지 않은 상태에서도 취약점공격이 가능하다. 해당 취약점은 bash subshell이 실핼될 때 { } 이후의 코드가 실행되는 취약점인데, 굳이 Shell을 통해서가 아니더라도 특정 프로그램이 Subshell을 실행한다면 취약점이 발현된다.



문제를 다시 살펴보면.

 

#include <stdio.h>
int main(){
	setresuid(getegid(), getegid(), getegid());
	setresgid(getegid(), getegid(), getegid());
	system("/home/shellshock/bash -c 'echo shock_me'");
	return 0;
}

eunice라는 환경변수에 함수로 인식되도록 등록하고 뒤에 ';'을 이용하여 'cat flag'가 실행되도록 정의한다.

그리고 shellshock바이너리를 실행하면 shellshock내부에서 권한 상승과 bash를 실행시키므로 취약점이 발현되어 flag가 출력된다.

 

**flag : only if I knew CVE-2014-6271 ten years ago..!!



잘못 된 개념을 서술하였거나, 잘못 풀이된 내용이 있으면 댓글 달아주시면 감사합니다 :)

태클 댓글이나 메일(513.eunice@gmail.com) 환영입니다 !! 😊☺️👍