Linux/서버 보안(CentOS)

접근권한[퍼미션]

D4tai1 2018. 10. 27.

1. 접근권한

1) chmod(Change Mode) 명령어

 - 접근권한을 부여 혹은 제거할 수 있는 명령어이다.

 # chmod [퍼미션] [파일 및 디렉터리]

 # chmod [대상][조작][종류]

 [1] 옵션

  ▶ -R = 해당 디렉터리의 모든 하위 파일에 대한 접근권한

 [2] 대상

  ▶ u = 소유자

  ▶ g = 소유자 그룹

  ▶ o = 기타 사용자

  ▶ a = 모든 사용자

 [3] 조작

  ▶ + : 권한추가

  ▶ - : 권한삭제

  ▶ = : 권한지정

 [4] 종류

  ▶ r : 읽기

  ▶ w : 쓰기

  ▶ x : 실행

  ▶ s : SUID or SGID

  ▶ t : 스틱키 비트

 [5] 사용 예

  ▶ chmod go+w test.txt

   - 소유자 그룹과 기타사용자에게 test.txt 파일의 쓰기 권한을 부여한다.

 

2) SUID(Set User ID)란?

 - 어떤 사용자가 프로그램을 실행해도 파일 소유자의 권한으로 실행된다는 것을 의미한다.

 - 권한에 4000을 더해서 부여하거나 [# chmod u+s "파일명"]  방식으로 부여한다.

 

3) SGID(Set Group ID)란?

 - 파일 소유자 그룹의 접근권한으로 실행된다는 것을 의미한다.

 - 권한에 2000을 더해서 부여하거나 [# chmod g+s "파일명"]  방식으로 부여한다.

 

4) Sticky Bit란?

 - 디렉터리에 쓰기는 가능하지만 소유자가 아니면 파일을 삭제할 수 없다.

 - 권한에 1000을 더해서 부여하거나 [# chmod o+t "파일명"] 방식으로 부여한다.

 - 디렉터리의 퍼미션을 확인해보면 실행권한이 t로 부여됨을 알 수 있다.  

 

5) 시연

 [1] 계정생성

 

 ▶ [# useradd test1; useradd test2] 명령어로 테스트할 계정 test1, test2 를 생성한다.

 ▶ [# sudo passwd test1], [sudo passwd test2] 명령어로 테스트계정의 패스워드를 지정한다.

 

 [2] 파일생성

 

 ▶ [$ cat > t1.txt] 명령어로 t1.txt 파일을 생성한다.

 ▶ [$ ls -l] 명령어로 파일정보를 확인한다.

 

 [3] 파일검색

 ▶ [$ find / -user root - perm +4000 2> /dev/null] 명령어를 이용하여 

소유자가 root인 SUID가 적용된 파일을 최상위 디렉터리에서 검색하고 에러가 발생할 경우 결과는 버린다.

 ▶ find 명령어에 관한 설명은 https://ccurity.tistory.com/7?category=662946를 참고하면 된다.

 

 [4] 디렉터리생성

 

 ▶ [# mkdir /work] 명령어를 이용하여 최상위 디렉터리 아래 work디렉터리를 생성한다.

 ▶ [# chmod 777 /work] 명령어로 누구나 접근하여 읽거나 쓸 수 있도록 한다.

 ▶ [# cat > test.txt] 명령어를 이용하여 새 파일을 생성한다.

 

 [5] test1계정으로 접근

 

 ▶ test1사용자가 root사용자의 파일 test.txt를 보거나 삭제할 수 있다.

 

 [6] 공유폴더

 

 ▶ test1계정으로 [# /tmp/test.txt] 를 생성한다.

 

 [7] test2계정으로 접근

 

 ▶ [$ cat >> /tmp/test.txt] 명령어로 test1소유의 파일을 수정한다.

 ▶ [$ cat /tmp/test.txt] 명령어로 파일이 수정된 것을 확인할 수 있다.

 ▶ [$ rm -rf test.txt] 명령어로 파일을 삭제하려고 하였지만 권한문제로 삭제할 수 없음을 확인할 수 있다.

 

 [8] 공유폴더 생성 

 

 ▶ [# mkdir /work1] 명령어로 디렉터리를 생성한다.

 ▶ [# chmod 1777 work1] 명령어로 디렉터리에 스티키비트를 부여한다.

 

 [9] 파일권한부여

 

 ▶ [8]에서 test1 파일을 만들었지만 무시하고 새 파일을 만들고 777권한을 부여한다.

 

 [10] root소유의 파일을 test1계정으로 접근

 

 ▶ [$ cat >> test] 명령어로 내용을 추가 후 내용을 확인한다.

 ▶ [$ rm - rf test] 명령어로 삭제해보려하지만 권한문제로 삭제할 수 없음을 확인한다.

 ▶ sticky bit를 부여하여 위의 /tmp 공유폴더와 같은 권한이 부여됨을 알 수 있다.

 

6) 사용시기

 [1] SUID와 SGID의 사용시기

  ▶ SUID는 보통 root계정으로 만들지 않는다.

  ▶ 만약 root계정으로 SUID를 부여할 경우 취약점에 의해 쉘이 실행된다면 root계정으로 쉘이 실행되어 시스템이 망가질 수 있다.

  ▶ 그럼에도 불구하고 사용하는 이유는 아무나 파일에 접근하여 수정하면 안되지만 해당사용자가 높은권한의 사용자의 권한을 빌려 사용해야 하는 파일의 경우에 사용한다.

  ▶ 예를 들면 [/usr/bin/passwd] 파일의 경우 패스워드를 변경할 때 root권한으로 실행해야하기 때문에 SUID가 부여되었다.

  ▶ 그러나 이 경우 취약점이 발견될 경우 위험하기 때문에 요즘에는 프로그램을 작성할 때 프로그램에서 필요한 순간만 권한을 변경하여 리소스에 접근하고 사용이 종료되면 정상적으로 원래 권한으로 되돌리는 방식으로 사용한다.

 [2] Sticky Bit의 사용시기

  ▶ 유닉스 리눅스는 여려 명이 사용하기 때문에 권한문제가 발생한다.

  ▶ 공유하는 폴더에 모든사람이 쓰고 삭제가 가능하지만 Stick Bit가 걸려있는 폴더는 접근권한이 있는사람이 쓸 수는 있지만 지우는 것은 파일 소유자만 가능하다.

 

7) 프로그램 작성

 [1] ruid

  ▶ Real User ID의 약자로 실제 본인의 프로세스 id를 의미한다.

 

 [2] euid

  ▶ Effective User ID의 약자로 SetUID 모드의 프로세스가 실행 중일 때 부여되는 파일 소유자의 id를 의미한다.

 [3] 예제코드(1)

 

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>

int main() {
	int _id;

	_id = system("id");

	printf("shell open \n");
	
	//system("/bin/bash");
	system("/bin/sh");

	return 0;
}

 

 ▶ bash는 ruid가 적용, sh는 euid가 적용(현재는 둘 다 ruid로 적용, 패치)된다.

 ▶ 그 이유는 Drop privilege 때문이다.

 ▶ Drop privilege는 sh, bash, system()을 실행 시 euid가 아닌 ruid의 권한으로 프로세스를 실행하는 것을 의미한다 

 ▶ SetUID가 설정된 파일에서 일시적으로 euid의 권한이 상승되어 중요시스템명령어 사용을 막기 위해서 사용한다.

  + sh는 dash를 의미한다.

  

 ▶그래서 setreuid(ruid, euid) 를 사용한다.

 [4] setreuid(ruid, euid) 란?

  ▶Set Real and Effective user ID 의 약어로 Real user ID와 Effective user ID를 설정하는 역활

 

  ▶ SetUID가 설정된 파일에서 setreuid (geteuid(), geteuid()) 를 사용하면 ruid가 euid로 변경 후

 

  ▶ bash 등 명령을 실행하면 ruid(현재 euid로 변경된) 실행

 

  ▶ 함수의 원형 -> int setreuid( uid_t* ruid*, uid_t *euid* );

 [5] 예제코드(2)

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>

int main() {
	int _id;

	_id = system("id");

	setreuid(geteuid(), geteuid());

	printf("shell open \n");
	
	//system("/bin/bash");
	system("/bin/sh");

	return 0;
}

 

 

  ▶ 위 소스를 컴파일 후 실행해보면 shell이 실행된다.

  ▶ 여기서 command injection을 시도하면

 
#include <stdio.h>
#include <string.h>

int main(char* argc, char* argv[]) {
	char cmd[60] = "/bin/ls ";
	
	strcat(cmd, argv[1]);
	system(cmd);

	return 0;
}

 

 

  ▶ 이 파일을 실행하면...?

  ▶ ; (세미콜론)을 이용하여 뒤에 추가로 원하는 명령어를 입력한다.

  ▶ 쉘을 얻기 위해 "/bin/sh"를 추가로 입력하였다.

 

 

  ▶ 쉘이 떨어지는 것을 확인이 가능하다.

'Linux > 서버 보안(CentOS)' 카테고리의 다른 글

파일암호화[대칭키]  (0) 2018.11.11
접근제어[사용자]  (0) 2018.11.11
SSH의 SCP 기능  (0) 2018.10.09
TCP Wrapper  (0) 2018.10.09
데몬관리  (0) 2018.10.04

댓글