해커스쿨 FTZ 구축 URL : http://noplanlife.com/?p=606
일단 level1의 패스워드는 level1이다.
level1 계정으로 접속하면 /home/level1 디렉토리로 접속될것이다.
해당 디렉토리의 파일들을 보자.
level1의 힌트이다. level2 권한에 setuid가 들어간 것을 찾으면 될듯 하다.
일단 find명령어가 떠오른다.. 그러면 옵션을 어떠한 것들을 주어서 찾아야 될까.
find /help 명령어로 옵션을 보기로 했다.
권한을 정해주는것 같은 -perm 옵션이 보인다. 사용자로 추정되는 -user 옵션도 보인다.
그러면 일단 setuid에 대해서 알아봐야 될듯하다.
하지만, setuid에 대해 알려면 먼저 permission(권한)에 대해 알아야 되겠지?
1. Permission(권한)이 왜 존재하는가?
UNIX는 DOS와 달리 Multi User OS이기 때문에, 여러명의 User가 하나의 Server에 접속할 수 있다. 그렇게 되면 각 User의 파일들에 대한 소유권이 있어야 되고, 그 소유권을 나누게 되는 룰이 Permission(권한)이다. 즉, user1이 생성한 파일을 user2는 읽고/쓰고/접근 한는 것들을 제어할 수 있게 하기 위해서 Permission이 생겨나게 됬다.
2. Permission(권한)이란?
허가라는 뜻으로 보통 "저 파일은 퍼미션이 열려 있다" 라고하는데 이 말의 뜻은 파일의 소유권자가 다른 사람들에게도 읽거나 쓸수 있도록 파일에 룰을 정해준 것을 말한다. 파일에 줄수 있는 대표적인 3가지 룰이 있는데 그것은 r,w,x라고 간단히 표시하며, 차례대로 읽기(read), 쓰기(write), 실행(excute) 이런 뜻이죠. 일반적으로 유닉스는 도스와는 달리 파일이름으로 실행파일이다. 읽기전용 파일이다 이렇게 구분하지 않는다. 도스에서는 확장자라는 개념이 있어서 bat,com,exe 라는 것이 실행파일이겠지만 유닉스에서는 x 라는 룰이 있을 경우 이 파일은 실행권한을 가졌다고 말한다.
3. Permission의 예..
위 사진을 보면
-rw-r----- 1 root shadow 1323 Jan 8 20:09 /etc/shadow
-rw-r--r-- 1 root root 2131 Mar 12 2015 /etc/passwd
이렇게 '/etc/shadow'파일과 '/etc/passwd'파일의 정보를 보았다. 먼저 '/etc/shadow'파일의 권한을 보자 '-rw-r-----'이렇게 표현되어 있다. 이때 맨 앞부분은 이 파일(-)이 파일인지 디렉토리(d)인지 디바이스 파일인지 구분하는 것이다.
그다음부터 9자리는 rwxrwxrwx 이렇게 권한이 주어지는 자리이다. 9자리중 앞 3자리는 파일을 만든 소유권자의 권한, 가운데 3자리는 파일의 소유자가 속한 그룹자들의 권한, 마지막 3자리는 나머지 사용자들에 대한 권한을 표현한다.
즉, '/etc/passwd'의 파일은 '-rw-r-----'이므로 파일 소유권자는 읽기,쓰기 권한이 있고, 그룹은 읽기 권한이 이쓰며, 나머지 사람들은 아무 권한이 없다는 것을 의미한다.
하지만, '/etc/passwd'파일은 나머지 사람들도 읽기 권한이 있다는 것을 볼 수 있을 것이다.
그럼 파일 소유권자와 그룹소유권자는 누구일까?
그건 바로 다음 정보를 보면 알 수 있다. '/etc/shadow'파일은 'root shadow' 이렇게 표현되어 있다. 이 정보를 통해서 소유권자는 root이고, 그룹소유자는 shadow라고 알 수 있다.
다시 정리하면 '/etc/shadow'파일은 root인 사용자는 읽기, 쓰기 권한을 갖고 있으며, shadow그룹에 속한 사용자들은 읽기 권한이 있는 것이다.
4. SetUID 란?
SetUID 라는 것은 임시적으로 사용자의 권한을 바꿔줄수 있는 룰을 파일에 적용시켜주는 것을 말한다. 일반 계정 이용자가 어떤 프로그램을 이용해야 하는데 이 프로그램은 root 만이 사용이 가능하게 만들어져 있다면 일반 계정 이용자가 그 프로그램을 돌리려면 루트가 되야된다. 하지만 아무에게나 루트를 줄 수 없는 법..... 결론은 그 프로그램이 돌때만 잠시 루트로 되게 하고 프로그램이 끝나면 원래 계정id로 돌아오는 방법을 택해야된다. 이럴때 바로 SetUID 라는 개념이 필요하다.
좀더 구체적으로 예를 들면, 보통 password 를 바꾸려면 유닉스에서 'passwd'라는 명령을 이용한다.
이런식으로 말이다. 그렇다면 그 바뀐 패스워드는 어디에 저장될까? 바로 '/etc/shadow' 라는 파일이다.그런데 앞에서 '/etc/shadow' 라는 파일은 -rw-r----- 으로 퍼미션이 설정되어있다. 이것은 일반 사용자로써는 접근이 불가능하다. 오로지 소유권이 root만이 쓰기가 가능하다. 그렇다면 우리의 일반 계정으로 돌린 프로그램이 어떻게 퍼미션이 닫혀 있는 /etc/shadow 파일에 바뀐 암호를 저장할 수 있을
까? 이때 setuid라는 특별한 권한이 존재하게 되는 것이다. setuid는 파일의 소유자 혹은 root 사용자만 설정할 수 있다. 'chmod' 명령어를 통해서 설정 할 수 있다.
'test'라는 파일에 chmod명령어를 통해 setuid를 설정하였다. 해당 파일의 권한을 다시 보자. 앞에서 보던거와 다르게 '-rwsr-x-r-x'로 설정되어 있다. 소유권자의 권한을 보면 'rws'이다 원래 대로라면 'rwx'가 되야 되는데 'x'자리에 's'가 들어가있다. 즉, setuid가 설정되어있다는 것을 의미한다. 이렇게 setuid가 설정되어 있으면, 해당 파일을 실행 할 때는 소유권자의 권한으로 실행할 수 있게 되는 것이다.
사진에서 눈치 챈것 처럼 setuid는 Permission이 4000이다. setgui(2000).
이제 다시 문제로 돌아와 문제를 풀어보자.
2가지 방법으로 파일을 찾을 수 있을것 같다.
1. 소유권자가 level2인 파일을 찾는 방법
2. 권한에 4000이 들어가있는 파일을 찾는 방법
먼저 1번째 방법으로 찾아보도록 했다. (find [검색위치] [-옵션])
원하는 파일들은 안나오고 'Permission denied'라는 내용이 적힌 쓸데없는 에러 메시지들이 표시된다.
A.
B.
C.
3가지의 Redirection명령어를 통해서 출력되는 정보들을 추려낼 수있다.
A와 B같은(1) 경우는 같은 의미로 STDOUT(standard output) C(2)의 의미는 STRERR(standard error)이다.
STDOUT은 표준출력으로, 정상적인 메시지를 출력하고 STDERR은 표준에러로, 에러메시지를 출력하는것이다.
다시 말해
B는 표준출력을 /dev/null로 redirection하고 (정상적인 메시지를 null로) => 에러메시지만 출력
C는 표준에러를 /dev/null로 redirection 한다 (에러메시지를 null로) => 정상적인 메시지만 출력
그렇다면 우린 정상적인 메시지만 출력하기 원하니까 '2>/dev/null'명령어로 Redirection 하면 될듯하다.
level2 소유권을 가진 파일 '/bin/ExecuteMe'파일을 찾아냈다.
해당 파일의 정보를 봐보자.
문제와 같이 소유권자는 level2이고 소유권자의 권한에 setuid가 설정되어 있음을 볼 수 있다.
그룹소유자는 level1이다. 즉, 지금 내가 접속된 계정은 level1이다.
그러므로, level1은 읽고,접근 가능하다는 것을 볼 수있다.
하지만 setuid가 설정되어 있으므로, 실행되는 순간의 권한은 level2로 설정된다.
그럼 해당 파일을 실행시켜 보자.
FTZ에서 해당 계정의 암호를 보는 명령어는 'my-pass'이다. 그리고 chmod는 파일의 권한을 설정하는 명령어다.
일단 쉘을 보니 level2의 권한을 취득했다. 위에 <사진 1-9>와 <사진1-10>의 쉘을 비교해서 보면 알 수있다.
level2의 권한을 획득해서 'my-pass'명령을 실행하면 level2의 암호를 알 수 있을것 같았는데, 'my-pass'명령을 사용하지 말라고 한다.=_=
그러면 현재 level2의 권한을 가지고 있으므로, 이상태에서 쉘을 다시 실행 시키면 어떻게 될까? 왠지 level2의 권한으로 쉘이 실행 될것 같지 않을까?
한번 실행 시켜보자.
역시 level2의 쉘로 실행되었다. 이렇게 setuid를 이용해서 level1에서 leve2의 권한으로 쉘에 접근하게 되었다.
이제 이상태에서 'my-pass'명령을 입력하면 level2의 패스워드가 출력될 것이다.