hint파일을 열어 level2 권한에 setuid가 걸린 파일을 찾으라는 문장을 확인할 수 있다.
먼저 setuid와 setgid 그리고 stickybit에 대해 알아보겠다.
setUID와 setGID는 파일에 다른 계정과 그룹의 권한을 일시적으로 빌려주는 개념이다.
setUID가 설정된 파일을 실행하게 되면 실행하는 동안은 그 파일의 소유자 권한을 지니게 된다.
예시를 통해 살펴보도록 하겠다.
그림과 같이 stickytest라는 파일을 만든 후 root만 사용할 수 있도록 권한을 준다.
root만 사용할 수 있으므로 root가 아닌 계정으로 파일내용 출력을 시도하면 거부되는 것을 확인할 수 있다.
uid와 euid를 출력하고 cat명령어를 통해 stickytest파일을 출력하는 stickybit.c파일을 만든다.
root계정에서 stickybit.c을 gcc를 통해 컴파일 후 root권한의 SUID와 SGID를 부여한다.
SUID는 (4000), SGID는 (2000)을 통해 설정가능하다.
그림상에서 6000에 해당하는 값을 주었기때문에 SUID와 SGID가 같이 설정된 것을 확인할 수 있다.
SUID와 SGID의 설정여부는 그림에서와 같이 s문자를 통해 확인가능하다.
root가 아닌 계정으로 stickybit를 실행시킨 결과이다. 위에서 Permission denied되었던 때와 달리 해당 파일은 root권한의 SUID가 설정되어 있으므로 실행 동안 root권한을 얻어 root 소유의 stickytest파일을 읽을 수 있게 된다. 또한 euid(Effective UID)값을 통해 현재 명령을 수행하는 주체의 uid가 root(0)이 된 것을 확인할 수 있다.
따라서 SUID와 SGID같은 기능을 이용한다면 다른 계정의 권한 획득이 가능해진다.
SUID를 사용하는 예는 /usr/bin/passwd가 대표적이다.
이어서 stickybit에 대해 알아보겠다.
root계정으로 /tmp디렉토리에 stickybit(1000)를 설정한 디렉토리인 stickytest를 만든다.
/tmp 디렉토리는 모든 계정이 공동으로 사용할 수 있는 디렉토리이다.
stickybit의 설정여부는 그림에서와 같이 t문자를 통해 확인가능하다.
stickytest/를 삭제, 수정을 시도한 결과 명령실행이 거부된 것을 확인할 수 있다.
stickybit가 설정된 디렉토리에서 rwx권한이 있기에 파일을 읽고 쓰고 실행할 수 있지만 root 또는 디렉토리의 소유자가 아니라면 해당 디렉토리를 삭제하거나 수정할 수 없다.
다시 문제로 돌아가 hint에 나온대로 setuid가 걸린 파일을 찾아보자.
level2권한에 setuid가 걸린 파일을 찾는 명령어는 다음과 같다.
find / -perm +4000 -user level2 2> /dev/null
핵심 옵션은 -perm +4000으로 setuid가 설정된 파일을 찾는다는 뜻이다.
(+ : 부여한 권한을 하나라도 만족하는 파일을 찾을 때 사용, - : 부여한 권한 모두를 만족하는 파일을 찾을 때 사용)
setgid가 설정된 파일을 찾을때는 -perm +2000옵션을 주면 될 것이다.
-user level2 옵션을 통해 level2권한으로 SUID가 설정된 파일을 찾을 수 있다.
마지막으로 2> /dev/null은 표준 오류 출력을 /dev/null로 전송하겠다는 의미이다.
2는 표준 오류 출력을 의미하며 0~2의 값이 존재한다. (0 : 표준입력, 1 : 표준출력, 2 : 표준 오류 출력)
/dev/null은 항상 비워진 상태로 /dev/null로 보내진 데이터는 삭제된다. (윈도우에서 휴지통과 비슷한 맥락이다.)
따라서 2> /dev/null을 통해 조건에 부합하는 결과만 확인할 수 있다.
(gdb를 이용한 /bin/ExecuteMe파일 리버싱은 글을 작성하는데 시간이 너무 오래걸릴꺼 같아 생략.)
리버싱을 통해 알아낸 핵심이라고 생각하는 요소는 다음과 같다.
빨간박스를 보면 level2권한의 bash shell 프롬프트가 떠있는 것처럼 보이지만 이는 실제 shell이 아닌 "[level2@ftz level2]$" 문자열이 출력된 것이다. 이는 입력값이 my-pass 또는 chmod 문자열의 입력여부를 확인하기 위한 조건문을 사용하기 위함으로 추측된다.
/bin/ExecuteMe 실행 결과 레벨2의 권한으로 하나의 명령어를 입력할 수 있다는 사실을 알았다.
또한 my-pass명령어를 실행불가하도록 설정해놓은 것으로 보아 my-pass에는 password가 들어 있을 것이다.
따라서 my-pass, chmod 문자열 필터링을 위해 shell인 척 존재하는 위조shell이 아닌 진짜 shell을 띄어 my-pass를 입력하면 될 것이다.
/bin/sh을 입력해 level2권한의 shell을 얻었다.
my-pass를 입력하면 Password를 획득하게 된다.
# root가 아닌 디렉토리 소유주의 디렉토리안에 root계정으로 생성되고 권한이 -rwx------인 파일을 디렉토리 소유주가 삭제할 수 있다. 왜냐하면 그 파일이 담겨있는 디렉토리는 해당 디렉토리의 소유주이기 때문이다.