Site icon DBA의 정석

SetUID의 위험성

SetUID와 Permission



잠깐 짬을 내서 SetUID 라는 것에 대해 짚고 넘어가고자 합니다.
SUID에 대해서 알기 위해서는 퍼미션(Permission)에 대해서 알아야 하죠.


1. 퍼미션이 왜 존재하는가?
; 유닉스는 도스와는 달리 멀티 유져 운영체제 입니다. 많은 사람들이 동시에 하나의
서버에서 일을 할 수가 있죠. 윈95나 98, 도스같은 시스템에서는 한개의 서버당 한명의
사람이 사용할 수 가 있죠. 이렇게 컴퓨터 한대를 한명이 사용할 때는 퍼미션이라는
개념은 전혀 필요가 없습니다. 하지만 여러명이 사용하는 유닉스 환경에서는 각각 개인을
구분 시켜줄 무언가가 필요했죠. 나우누리,하이텔,천리안 같이 아이디로써 상대방을
구분하듯이요.. 만약 나우누리,하이텔,천리안 같은 대형 통신망에서 모든 사람이 하나의
아이디로 지낸다면 엄청 불편하겠죠. 그렇기 때문에 각자의 아이디가 있고 또한 상대방의
영역을 침범하지 못하게 해 놓았죠. 상대방의 프라이버시를 침해하지 않도록요..
유닉스도 똑같아요. 개개인의 아이디가 존재하고 개개인의 아이디가 만들어내는 파일을
남이 읽지 못하게 하려면 퍼미션이라는 개념으로 파일에 대한 룰을 할당하는 거죠.
대형 통신망의 시삽과같이 모든 것을 통제할 수 있는 권한을 가진 사람이 있는 것처럼
유닉스도 root라는 모든 것을 통제할 수 있는 권한이 있답니다.


2. 퍼미션이란?
; 허가라는 뜻으로 보통 “저 파일은 퍼미션이 열려 있다” 라고하는데 이 말의 뜻은 파일의
소유권자가 다른 사람들에게도 읽거나 쓸수 있도록 파일에 룰을 정해준 것을 말해요.
파일에 줄수 있는 대표적인 3가지 룰이 있는데 그것은 r,w,x라고 간단히 표시하며, 차례
대로 읽기, 쓰기, 실행 이런 뜻이죠. 일반적으로 유닉스는 도스와는 달리 파일이름으로
실행파일이다. 읽기전용 파일이다 이렇게 구분하지 않아요. 도스에서는 확장자라는 개념이
있어서 bat,com,exe 라는 것이 실행파일이겠지만 유닉스에서는 x 라는 룰이 있을 경우 이
파일은 실행권한을 가졌다고 말할 수 있죠.


3. 퍼미션의 예..
; /etc/passwd 파일을 보면,
$ ls -al /etc/passwd
-rw-rwxr– 1 root wheel 1608 Aug 13 09:48 /etc/passwd


여기서 대충 퍼미션의 부분과 소유권 부분을 알아봅시다. 여기서 root wheel 라고 되어있는
부분은 /etc/passwd 파일의 소유권이 누구이고 그룹이 누구인지를 알려줍니다. 여기서는
root 소유권이며, wheel 이라는 그룹으로 되어있군요. 참고로 유닉스에서는 각 개인을 나타
내는 ID 와 그룹이라는 개념이 존재합니다. 개인 id 야 발급해서 받는 것이며, 그룹이라는
개념은 그 비슷한 사람들 끼리 묶어 놓는 것이에요. 그룹은 이럴때 아주 유용하죠..


그 다음, -rw-rwxr– 이라고 되어있죠? 앞의 – 는 파일인지,디렉토리인지,디바이스 파일
인지를 구분, rw- , r– , r– 이렇게 되어있는데 앞의 단은 파일은 만든사람 즉, 소유자에
대한 퍼미션(rw:읽고,쓰기가능), 두번째 단의 rwx 은 파일의 그룹소유권에대한 퍼미션(rwx :
읽기,쓰기,실행 가능) 세번째 단은 r– 은 시스템 내의 모든 사용자에 대한 퍼미션
(r–:읽기만 가능)을 나타내는 거죠.


자 그럼 이것을 종합하자면 /etc/passwd 파일의 소유자는 root 이고 그룹소유자는 root 이랍니다.
그리고 퍼미션은 모든 사용자에게는 읽기만을 허용하고, 같은 그룹 사용자들에게는 읽기,쓰기,
실행이 가능하며, 파일 소유자인 root에게는 읽기쓰기가 가능하답니다.
이제 이해가 가시나요?


(예제)
$ ls -al /etc/shadow
-r——– 1 root root 1736 Aug 12 10:41 /etc/shadow 이것의 정보는 어떤가요?
/etc/shadow 파일의 정보를 보여준 것으로 소유권은 root 이며, 그룹 소유권은 root이며,
모든 사용자에게는 퍼미션이 닫혀있죠? 그리고 오로직 root 에게만 읽기 권한 하나만 열려
있답니다. /etc/shadow 파일은 바로 계정이용자의 비밀번호가 담겨져 있어서 그렇답니다.


4. SetUID 란?
SetUID 라는 는 것은 임시적으로 사용자의 권한을 바꿔줄수 있는 룰을 파일에 적용시켜주는
것을 말해요. 일반 계정 이용자가 어떤 프로그램을 이용해야 하는데 이 프로그램은 root
만이 사용이 가능하게 만들어져 있답니다. 그렇다면 일반 계정 이용자가 그 프로그램을
돌리려면 루트가 되야겠죠? 하지만 아무에게나 루트를 줄 수 없는 법…..
결론은 그 프로그램이 돌때만 잠시 루트로 되게 하고 프로그램이 끝나면 원래 계정id로
돌아와야겠죠. 이럴때 바로 SetUID 라는 개념이 필요한 것이 아닐까요? 좀더 구체적으로
예를 들어볼까요? 보통 password 를 바꾸려면 유닉스에서 어떤 명령을 내릴까요?
$ passwd
Changing password for user bugscan
New UNIX password:
Retype new UNIX password:
이런식으로 바꾸죠? 그렇다면 그 바뀐 패스워드는 어디에 저장될까요? 바로..
/etc/shadow 라는 파일이죠. 아~~ 기억나세요? /etc/shadow 라는 파일은 -r——– 으로
퍼미션이 설정되어있어요. 저기 위를 보시길.. 이것은 일반 사용자로써는 접근이 불가능
하죠. 오로지 소유권이 root만이 읽기만 가능해요. 그렇다면 우리의 일반 계정으로 돌린
프로그램이 어떻게 퍼미션이 닫혀 있는 /etc/shadow 파일에 바뀐 암호를 저장할 수 있을
까요? 이런 의문이 있는 사람도 있을꺼에요. 그냥 passwd 라는 프로그램이 /etc/shadow
파일을 바꾸지 않아요? 하지만 프로그램을 실행시킬때 아무리 프로그램이 굉장해도 실행
시킨 사람의 권한 이상의 일을 못한답니다. 그게 규칙이죠. 이제 suid 개념이 나와야 하겠
네요. suid는 파일의 소유자 혹은 root 사용자만 설정할 수 있어요. chmod 라는 퍼미션을
설정하는 프로그램을 이용하죠.
-rwsr-xr-x 1 level1 level0 12900 Jul 27 15:00 /aa
이런 경우가 바로 suid 가 걸려 있는 경우랍니다. 퍼미션이 설정된 부분을 보세요. 일반적
으로 퍼미션 설정은 rwx이런 식으로 되어있는데 x 대신 s 라는 것이 있죠. 이때가 바로
소유권에 suid 가 걸려 있어요. 어떤 사용자라도 /aa 라는 프로그램을 실행하면 그 실행되는
순간 만큼은 level1 이라는 파일 소유권의 권한을 가지게 되는 거죠. 프로그램이 종료되면
다시 원래 자신의 권한으로 돌아와요. 이런 것들이 바로 suid 설정이랍니다. 길게는 SetUID
라고도 하며 줄여서 suid 라고 하죠.



5. SetUID의 위험성
잠시 setuid 라는 것을 짚고 넘어가자면 파일에 설정되는 룰중에 하나로 어떤 사람이든 그
룰이 설정된 파일을 실행하면 그 파일의 소유권의 계정(ID)으로 그 프로그램이 돌게 되죠.
혹시 cat 이라는 명령을 아시나요? 이 프로그램은 파일을 읽거나, 쓸수 있는 기능을 가지고 있죠.
예를 들면, $ cat /etc/passwd 라고 하면 /etc/passwd 파일을 읽죠. 만약 bugscan 이라는
사람이 만든 파일이 있는데 퍼미션이 일반 사용자들 한테는 닫혀 있다고 합시다.
즉, 이런 식으로 퍼미션이 설정되어있다고 보면 될꺼에요..


-rw——- 1 bugscan admin 45147 8월 19일 15:45 /tmp/passwd
(세번째 단이 — 으로 되어있으므로 일반 사용자들한테는 퍼미션이 닫혀 있어서 읽지도 실행
하지도 쓰지도 못한다. 오로지 파일 소유자만이 읽고 쓸수 있다.)


$ whoami
guest
$ ls -al /tmp/passwd
-rw——- 1 bugscan admin 45147 8월 19일 15:45 /tmp/passwd
$ ls -al /bin/cat
-r-xr-xr-x 1 bin bin 9388 Jul 16 1997 /bin/cat
$ cat /tmp/passwd
cat: cannot open /tmp/passwd


보다 시피 /tmp/passwd 파일은 있지만 cat 으로 파일을 열수 없다고 나오죠? 바로 guest 와 같은
bugscan 과 다른 아이디의 사용자 에게는 퍼미션을 열지 않아서 겠죠.


자 한번 이번에는 이런 식으로 되어있을 경우 /tmp/passwd 파일을 읽을 수 있죠.


$ whoami
guest
$ ls -al /tmp/passwd
-rw——- 1 bugscan admin 45147 8월 19일 15:45 /tmp/passwd
$ ls -al /bin/cat
-r-sr-xr-x 1 bugscan bin 9388 Jul 16 1997 /bin/cat
$ cat /tmp/passwd
어쩌구 저쩌구. 패스워드가 여기있고, 저기있고.. 여기도 있었군. 이제 없나보다..


지금은 /tmp/passwd 파일을 읽을 수 있죠.. 왜 그럴까요?
그 해답은 바로 /bin/cat 라는 파일의 퍼미션을 보시면 될꺼에요.
cat 의 소유권은 bugscan 이고 setuid 가 걸려 있죠.
즉, 현재의 guest 사용자는 cat 이라는 프로그램을 돌리는 순간만큼은 bugscan 이라는 아이디로
돌아간것이죠.. 그렇기 때문에 퍼미션이 닫혀진 /tmp/passwd 파일을 읽을 수 있는 것이고요..


그럼 이번에는 cat 프로그램이 아닌 /bin/more 라는 프로그램을 살펴봅시다.
more 라는 프로그램도 cat과 같이 파일을 읽을 수 있는 기능을 가지고 있습니다.
하지만 cat 명령과 다른 점은 한페이지가 넘는 문서 파일일 경우 아무키나
누르도록하고 화면을 정지 시킵니다.
도스의 dir /p 명령과 같이 p 옵션을 줘서 화면을 멈추게 하는 거죠.
cat 대신 more 라는 파일에 setuid 를 주고 다시 한번 /tmp/passwd 파일을 봅시다.


$ whoami
guest
$ ls -al /tmp/passwd
-rw——- 1 bugscan admin 45147 8월 19일 15:45 /tmp/passwd
$ ls -al /bin/cat
-r-sr-xr-x 1 bugscan bin 21418 Jul 16 1997 /bin/more
$ more /tmp/passwd
어쩌구 저쩌구.
패스워드가 여기있고, 저기있고..
여기도 있었군. 이제 없나보다..
….
….
….
–More–(2%)



아까 cat 명령을 내렸을 때 와 별 다른거 없죠? 다만 –More–(2%) 라는 것이 나와서 페이지
별로 내용을 볼수 있을뿐.. 하지만 more 의 내부 명령중 이런 것이 있죠.. ! 라는 명령이 핵심입니다.
! (느낌표) 명령은 그 뒤에 붙인 파일이름을 실행하라는 명령과 같아요.
즉 이렇게 명령을 내릴수가 있죠.
!cat /tmp/passwd 라고 명령을 내리면 현재의 권한으로 cat /tmp/passwd 명령을 내리죠.


아!!! 잠깐 여기서..


현재의 권한으로 cat /tmp/passwd 명령을 내린다고 했죠?
한가지 간과하고 넘어간 부분은 바로 suid 가 걸린 프로그램을 실행시키는 순간은 파일의 소유자
권한이라고 했죠? 그렇다면 프로그램의 종료가 아닌 중간에 ! 명령으로 임시 명령을 내리는 순간에도
setuid는 유효하다 이말이죠. 결국 중간에 !cat /tmp/passwd 라고 해도 /tmp/passwd 파일은 보인다는
거죠. 이제 좀 눈치가 생기나요?



6. /bin/sh 라는 파일은 뭐하는 건가?
/bin/sh 라는 것은 아주 여러분이 실행시키고, 무의식적으로 넘어가는 부분이죠.
/etc/passwd 파일을 한번 살펴보세요.


% cat /etc/passwd
proto40M:x:9683:200:Quota Proto 40M:/tmp:/bin/sh
proto30M:x:9684:200:Quota Proto 30M:/tmp:/bin/sh
proto20M:x:9685:200:Quota Proto 20M:/tmp:/bin/sh
proto10M:x:9686:200:Quota Proto 10M:/tmp:/bin/sh
proto3M:x:8000:200:Quota Proto 3M:/tmp:/bin/sh
proto50M:x:9687:200:Quota Proto 50M:/tmp:/bin/sh
proto70M:x:7833:200:Quota Proto 70M:/tmp:/bin/sh
….


맨 끝부분에 /bin/sh 라고 되어있지 않은가? 한번 각 서버의 /etc/passwd 파일을 읽어보기 바래요.


/bin/sh(쉘:SHELL) 파일의 쓰임은 흔히 사용하는 도스의 command.com 파일과 같다고 생각하세요.
“명령어 해석기” 라고도 부르죠.
우리가 일반적인 유닉스 로그인을 하게 되면 /etc/passwd 파일의 마지막에 붙어있는 /bin/sh 가 실행
되면서 prompt가 뜨게 되죠. $ 혹은 # 이런식으로요. 바로 쉘이 실행된것을 뜻하죠..
쉘이 뜨면 그때부터 유닉스의 모든 명령을 내릴수가 있는 거에요..
/bin/sh 파일에 손상이 가거나 삭제되면 로그인을 못하게 되는 결과를 낳게 되죠.


그렇다면 이런 식의 행동은 어떤 결과를 부를까요?


more 를 사용하는 과정에서 !/bin/sh 라고 치게 되면 어떻게 되나요? 쉘을 실행했으니 $ 화면이
나오겠죠? 또한 현재 실행되는 suid 는 유효할테고… 그렇다면 whoami 를 이상태에서 치면 bugscan
이라고 나오지 않을까요? 내리는 명령마다 bugscan 으로 실행할 수 있겠죠.. 왜냐… setuid는 아직
까지도 유효하기 때문이죠.. 아직 more 프로그램은 종료된게 아니라 more 의 ! 라는 내부 명령어 안에
있는 것이기 때문이죠.


다음은 당신이 계정에 접속한후 more 를 실행해 !로 쉘로 빠진 경우를 보여줍니다.
login -> /bin/sh -> more -> ! -> /bin/sh -> ls , cat, vi, telnet , ftp .. 등등


7. 루트쉘(RootShell)
; setuid 가 root 로 되어있는 쉘을 말합니다.
setuid는 무엇인지 아시겠죠?
실행할 파일이 /bin/sh 이고 그 소유권이 root 인 경우 어떤 모습일까요?


-r-sr-xr-x 3 root 88620 Jul 16 1997 /bin/sh


바로 이런 모습이겠죠?


일반적인 정상적인 /bin/sh는 이렇습니다.


-r-xr-xr-x 3 root 88620 Jul 16 1997 /bin/sh


맨위의 /bin/sh를 실행하는 순간 우리는 setuid 가 걸려 있기때문에 root가
되는 거죠.
쉘 자체를 루트로 실행하는 거랍니다.
다음의 예제를 보세요.


$ whoami
guest
$ ls -al /bin/sh
-r-sr-xr-x 3 root 88620 Jul 16 1997 /bin/sh
$ /bin/sh
# whoami
root
# exit
$ whoami
guest



이제 아시겠죠?
쉘 자체가 종료될때까지는 setuid 가 유효 하답니다.


8. 퍼미션 설정 방법
우선 일반적인 rwx 모드 부터 봅시다.


chmod 숫자(퍼미션) 파일이름


보통 이런 방법을 많이 사용합니다. 이런 방법외에도 숫자 대신 직접 퍼미션 모드 이름을 넣을
수도 있지만 숫자를 조합해서 만드는 것이 가장 편합니다.


숫자란에다 넣을 수 있는 규칙은 아주 간단합니다.
r = 4 , w = 2 , w = 1 로 계산을 하는 거죠.
또한 세단으로 나눠지는 퍼미션을 생각해야 겠죠.
rwxrwxrwx 이런 식으로요.. 자 그러면 이런 예제를 보시면 금방 규칙을 알 수
있을꺼에요.


퍼미션 : rwxrwxrwx
4+2+1 + 4+2+1 + 4+2+1 = 777 ( chmod 777 file_name )


퍼미션 : rwx—r-x
4+2+1 + 0+0+0 + 4+0+1 = 705 ( chmod 705 file_name )


퍼미션 : r-xrw—x
4+0+1 + 4+2+0 + 0+0+1 = 561 ( chmod 561 file_name )


퍼미션 : –x–x–x
0+0+1 + 0+0+1 + 0+0+1 = 111 ( chmod 111 file_name )


다음은 setuid 설정이에요.
setuid 는 3자리 숫자가 아닌 하나더 추가해서 사용해요. 4자리 숫자 주의 해야 할 점은 setuid
가 걸린 프로그램은 실행권한이 있어야 해요.


퍼미션 : rws——
4 + 4+2+1 + 0+0+0 + 0+0+0 = 4700 ( chmod 4700 file_name )


퍼미션 : –sr-xr-x
4 + 0+0+1 + 4+0+1 + 4+0+1 = 4155 ( chmod 4155 file_name )


* 만약 4155 가 아닌 4055 로 하면 실행이 안되죠.
# chmod 4055 sh
# ls -al sh
—Sr-xr-x 1 bugscan informix 88620 Aug 20 02:54 sh*
# ./sh
./sh: Permission denied.
# chmod 4155 sh
# ls -al sh
—sr-xr-x 1 bugscan informix 88620 Aug 20 02:54 sh*
# ./sh
$ whoami bugscan

Exit mobile version