심심해서 하는 블로그 :: 심심해서 하는 블로그

1. Overview

접근제어(Access Control)란??

접근제어는 자원에 대한 권한이 없는 주체(Subject)가 해당 자원의 사용을 막는 것을 의미한다.

접근제어를 하기 위해서 주체를 구별하기 위한 Identification과 본인 여부를 확인하는 인증 절차가 필요하다.

특히 인증의 성공 여부에 따라 리소스에 접근할 권한을 줄지 안 줄지 결정되므로 인증이 핵심 절차이다.


주체(Subject)는 컴퓨터를 사용하는 사람, 그룹, 프로세스, 컴퓨터와 같이 정보를 요청하는 요소이며,

객체(Object)는 파일이나 폴더, 디바이스, 메모리 등 정보를 가지고 있는 요소이다. 

주체는 접근 권한에 따라 객체를 읽거나, 쓰기, 실행이 가능하며 권한은 객체별로 다른 형태로 부여한다.


요구사항

- 신뢰가능한 입력(reliable input) : 신뢰가능함은 인증을 통과한 주체가 행하는 입력을 의미한다.

- 포괄적 vs 세분화 : 권한의 범위를 어느 수준까지 설정하는가 문제

- 최소 권한 : 주체에게 너무 큰 권한을 부여하면 시스템의 문제의 여지가 될 수 있다.

- 열린 정책 vs 닫힌 정책 / 정책 간 충돌 문제

- 정책 관리 : 관리자만이 정책을 변경할 수 있다.

- 동시성 제어 : 하나의 객체에 여러 주체가 동시에 접근할 경우 어떻게 처리할지 문제

- 의무의 분리 : 중요한 행위는 반드시 두 개이상의 user나 권한으로 나누어서 실행한다.


2. DAC(Discretionary Acess Control)

주인장 맘대로

자원의 주인이 해당 자원에 대한 다른 사람들의 권한을 결정하여 접근 제어를 하는 방법이다.

따라서 이 방법을 사용하기 위해서 각자를 구별할 ID와 해당 자원의 소유권, 그리고 다른 유저에게 분배된 권한을 정리할 파일이 필요하다. 권한을 저장하는 방법은 Access Control List, Capability List, Access Matrix가 있다. Access Matrix의 경우에는 사용자가 많고 자원들이 많은 실제 상용 시스템에서 사용하면 공란이 많은 희소 행렬의 형태라 공간 낭비가 심해 사용하지 않는다.




Access Control List vs Capability List

ACLs는 자원에 대하여 각 사용자들의 권한을 저장하는 방법이고 CL은 반대로 사용자에 대하여 각 자원들의 권한을 저장하는 방법이다. 다시 말해 ACLs는 자원 중심, CL은 사용자 중심의 저장 방법이다. 따라서 사용자에 비해 자원이 많은 개인용 PC 같은 환경에서는 ACLs, 사용자의 수가 많은 웹 서버같은 환경에서는 CL이 더욱 유용한 방법이다. 


DAC 장점

- 사용자가 접근 권한을 관리 할 수 있어서 보안 관리자가 업무가 줄어 든다.

- 권한을 수정이 쉽고 새로운 권한을 적용하기 쉽다.


DAC 단점

- 위의 그림처럼 권한을 부여한 사용자의 의도하지 않은 대로 정보가 흘러갈 수 있다.

- 루트의 권한이 너무 강력하다. 

- 주체와 객체의 수가 증가한다면 복잡해지고 크기가 커지는 문제도 있다.

- 소유자를 쉽게 변경이 가능하다는 점을 악용한 프로그램들도 많다 



Unix / Linux의 파일 시스템

리눅스의 파일 시스템의 정보는 inode 저장된다. inode에는 하나의 파일 또는 디렉터리의  UID, GID, 소유권이 명시 되어있으며 12개의 비트로 특수권한 / 읽기 / 쓰기 / 실행 권한을 표기한다. 이 inode들은 디스크 상에 inode 테이블이나 리스트에 저장이 되어진다. 그리고 파일을 열면 해당 파일의 inode는 메인 메모리에 상주하는 inode 테이블에 저장된다. 


DAC 취약점 실습


위 그림은 file1의 소유주 csos가 user1에게 읽기 권한을 부여하는 과정이다.


리눅스에서 setfacl 또는 chacl 명령어로 파일 시스템 상의 ACL을 변경할 수 있고 getfacl 명령어로 해당 파일의 ACL정보를 확인 할 수 있다. 파일의 소유자의 UID, GID 정보와 각 사용자와 그룹에 대하여 권한, 마스크 정보도 추가된 확장된 ACL을 사용한다는 것을 알 수 있다. 파일 시스템에 접근하는 경우 파일의 ACL을 확인하여 소유자 -> 지정한 유저 -> 그룹 -> 외부자로 순으로 연산 처리한다.



user1으로 접속을 변경하고 csos가 읽기 권한을 준 file1을 복사하여 user1의 영역으로 복사하였다. 이제 user1은 file1의 사본 file2의 소유자이므로 file1에 대한 모든 권한을 행사할 수 있다. 이처럼 DAC는 원 소유자 csos의 의도와 다르게 흐름을 변경할 수 있는 취약점이 있다.

,

1. ISAM 트리구조

정적 트리구조

삽입 / 삭제를 하여도 트리의 구조가 변화하지 않는 것이 특징이다. 만일 페이지에 더 이상 데이터를 추가할 수 없다면 오버플로우 페이지를 생성하여 마지막 리프노드에 체인으로 연결하여 추가한다.


오버플로우 페이지

위의 그림 왼쪽 트리 구조에서 7을 삽입하는 연산이 수행한다고 가정하자. 루트에서 시작해서 리프 노드에 도달하면 7이 들어갈 노드가 (6*, 9*)로 채워져 들어갈 공간이 없다. 이때 ISAM 트리 구조는 트리의 구조를 변형시키지 않고 아래에 7이 들어갈 수 있는 공간을 만든 후 다음 7을 삽입한다. 이 때 새로 만들어진 이 공간을 오버플로 페이지라고 한다. 


오버플로 페이지를 생성함에 따라서 얻을 수 있는 이득은 오버플로가 발생하는 경우 삽입 / 삭제 연산이 B+ 트리보다는 빠르다는 점이다. 아래에 설명할 B+트리는 동적 트리구조로 만약 위의 그림과 같은 상황이 발생하면 트리 구조를 변형을 하여 삽입을 시도하기 때문이다. 또한 Lock을 거는 경우 트리의 내용물에는 변화가 없기 때문에 리프 노드에만 Lock을 걸면 된다. 하지만 오버플로 페이지가 많이 발생할수록 위 그림에서 눈치챘을지도 모르지만 데이터를 물리적으로 정렬하지 않기 때문에 데이터를 탐색하는 속도는 늦어어진다는 단점이 있다.


2. B+ 트리구조

적 트리구조

ISAM 트리와 달리 삽입 / 삭제시에 트리구조가 변화가 발생하는  특징이 있다. 또한 Root 노드를 제외한 나머지 노드들은 데이터를 반드시 절반 이상 점유해야 하는 필수 조건이 있다. 



삽입 연산

위의 트리에서 8을 삽입한다고 가정하자. 8은 L2에 삽입되어야 하지만 현재 노드가 꽉 차있어서 삽입을 할 수 없다. B+ 트리는 오버플로 페이지를 생성하지 않고 L2를 쪼개서 새로운 노드를 만드는 방법을 사용한다. 8을 포함한 L2의 구성 요소 (5,6,7,8,9) 중 중간 값인 7은 상위 단계 노드로 Copy up 되고 트리구조의 특징상 기존의 L2(5,6,7,8,9)는 L2(5,6), L3(7,8,9)로 갈라지게 되어 아래 그림과 같이 된다.



따라서 삽입 연산 중 리프 노드에서 오버플로가 발생하면 B+트리는 해당 노드의 중간 값이 상위 노드로 Copy up 하는 과정이 발생한다. 만일 Copy-up 과정에서 상위 레벨 노드마다 오버플로가 발생한다면 어떻게 트리구조가 변화할까?



위의 그림과 같은 트리에서 15가 삽입된다고 가정하자. 15가 삽입될 노드는 L4인데 L4가 가득 차있으니까 아까 위에서 Copy up을 시도한다. L4(13,14,15,16,18) 중에서 중간 값인 15가 상위 단계 노드로 Copy up이 되려는 순간 상위 노드가 꽉 차있다. 따라서 상위 노드도 분열이 되어야 하는데 이 과정에서 분열된 상위 노드들을 연결할 새로운 루트 노드가 필요하다.  상위 노드의 값 (5, 7, 13, 15, 20) 중 중간 값인 13이 한 단계 상승한 Push up 과정이 발생하고 나머지 (5,7) (15,20)이 다음 노드로 연결되는 아래 그림과 같은 트리구조로 변화한다.



기존 트리의 높이는 1이였지만 삽입의 결과로 높이가 2로 변화하였다. B+트리는 이처럼 트리의 구조를 유지하기 위해서 Copy up / Push up 알고리즘을 사용하고 경우에 따라서 트리의 높이가 변화할 수도 있다.


삭제 연산

삭제 연산에서 가장 중요한 키워드는 루트를 제외한 각 노드는 점유율을 항상 50%이상 유지한다는 점이다. 만약 50프로가 안된다면 인접한 노드에서 빌려온다. 그런데 빌려 오니까 인접 노드도 점유율 50%를 만족하지 못한다면 인접 노드와 병합하는 방법으로 점유율 50%를 유지한다.


 

위 그림(아까 삽입한 결과)에서 24*를 삭제하는 연산을 수행한다고 하자. L6은 이제 데이터가 (21*)만 존재하게 되어 데이터의 점유율이 50프로 미만이 되어버렸다. 따라서 인접 노드인 L5에서 데이터를 (18*)를 빌려온다. L5도 (15*, 16*)을 가지고 있고 L6도 (18*, 21*)로 50프로를 유지할 수 있으므로 L6의 최솟값 18*을 상위 노드에 20*으로 Copy up 하는 것으로 마무리한다. 결과는 아래의 그림과 같다.



이번에는 L1의 1을 삭제한다고 가정하자. 1이 삭제된 L1은 (2*)만 남아 50프로를 유지할 수 없고 인접 노드 L2의 5*를 빌려서 채울려고 하지만 그렇게 진행하면 L2도 (6*)만 남아 점유율 50프로를 만족하지 못한다. 따라서 L1과 L2는 합병이 된다.



합병을 하고 상위 노드 I1의 5*를 삭제하니 I1도 50프로를 만족하지 못한다. 인접 노드 L2에서 데이터를 하나 빌릴려고 하니 연산 결과 L2도 50%를 만족하지 못한다. 따라서 합병을 해야하는 상황이 발생한다. 



합병을 할 때 상위 노드의 값은 한 단계 내려와 Pull down되어 I1, I2와 함께 합쳐진다.  그 외 여기서 다루진 못했지만 만약 I1이 데이터가 4개 있고 삭제당한 I2의 데이터가 1개 있다면 합병하게 되면 5개가 돼버려서 오버플로가 발생하는 경우가 있다. 이 경우에는 재분산(Re-distribution)을 사용하여 2개 / 3개로 다시 나누어 주는 과정이 있다. 기존의 트리의 높이는 2였지만 모든 삭제 연산을 수행한 후에 보면 높이 1의 트리로 변화하였다. 


트리 구조를 유지하면서 이득 / 손해

우선 이득은 데이터 탐색 속도가 ISAM보다 빠르다. 오버플로 페이지가 발생하지 않고 데이터가 삽입되면 그 데이터를 물리적으로 정렬하기 때문이다. 대신 삭제나 삽입의 경우 트리 구조를 유지해야 하는 면에서 ISAM에 비하면 복잡한 과정이 있기 때문에 비용이 좀 더 드는 손해는 있다. 하지만 인덱스를 사용하는 이유는 탐색 속도의 향상이므로 대부분 상용 DBMS에서는 B+ 트리를 사용하여 인덱스를 만든다.

,

1. Rainbow Table attack

답지를 들고 있단다.

앞서 비밀번호는 대부분 해시함수를 사용하여 그 결과 값을 데이터베이스에 저장한다고 했다. 따라서 복호화가 불가능한 상태라 평문(비밀번호)의 내용을 관리자한테까지 숨길 수 있는 장점을 가지고 있다. 이에 따라 공격자들은 사전에 해쉬함수에 입력한 값과 해쉬 결과 값을 저장한 일종의 정답지(Rainbow Table)를 가지고 비밀번호를 확인 할 수 있게 되었다. 이런 공격 우연하게 같은 비밀번호를 사용하는 경우에 여러 계정이 동시에 피해를 볼 수 있는 단점이 있다. 따라서 이 공격에 대안으로 Salted hash가 등장하였다.


2. Salted hashed

양념을 촵촵촵

기존에는 패스워드만 해시함수에 통과시켰으나 최근에는 가입 시간이나 난수(Random Number)를 비밀번호와 같이 해시 값에 포함한다. 이 때 추가적으로 포함된 가입 시간이나 난수를 Salt라고 한다. 치킨에다가 양념을 어떤 것을 사용하냐에 따라 맛이 달라지 듯이 서로 다른 계정이 같은 비밀번호를 사용하더라도 Salt가 다르면 완전 다른 해시 값이 달라지며, 설령 같은 해시 값을 같더라 하여도 Salt 값이 전혀 다르기 때문에 평문을 유추하기 힘들다. 이 Salt는 해쉬 결과 또는 Salt 평문을 패스워드 관리 테이블에 같이 보관한다.


Salted hash의 경우 Salt의 길이가 길면 길수록 무차별 대입공격이 강력하다. OpenBSD는 Blowfish라는 블록 암호화 기법을 가지고 있으며 128bit의 Salt를 사용하여 192비트의 해시 값을 만들어 낸다.


시간을 끌자

해시 함수는 암호화보다 소요하는 시간이 짧다. 따라서 암호문을 무차별 대입으로 푸는 것보다 해시함수에 무차별로 대입하는 것이 소모하는 시간이 짧아 이 시간을 늘려야 할 필요성이 있다. 이에 따라 개발자들은 해시함수를 1000번이상 반복으로 실행하여 고의적으로 시간을 늦추려 하고 있다. 


3. Bloom Filter

사용자 교육의 한계

뉴스에서 보안 사고가 발생하여도, 청개구리 같은 사용자들이 많다. 비밀번호를 길고 자연어 사용을 제한하고 취약한 비밀번호 사용을 금지해도 외우기 귀찮고 손에 안 익는 비밀번호를 사용하기 싫어서 무시하고 사용하며, 일정 주기마다 비밀번호를 변경하라는 메세지가 뜨면 "다음에 할게요~ㅎㅎ" 하고 그냥 넘어가 버리는 경우도 많다. 따라서 말 안듣는 사용자를 교육시키기보다 애시당초 시스템에서 보안이 취약한 비밀번호에 대하여 거절을 하게 만든다.


너만 갖고 있냐?? 나도 갖고 있어!!

Rainbow Table은 공격자도 가질 수 있지만, 개발자들 또한 해당 테이블을 가질 수 있다. 따라서 개발자들은  
사용자가 회원가입할 때 Rainbow Table에 있는 비밀번호에 대하여 사용을 금지하는 방법을 선택하는데 이러한 과정을 Proactive Password Checking이라 하며 금지된 비밀번호를 걸러 내는 필터를  Bloom Filter라고 한다. 이 방법을 사용하면 사용자는 취약한 비밀번호를 사용이 금지되어지며 공격자가 가지고 있는 패스워드 사전도 취약하게 된다. 설령 공격자가 갱신을 한 패스워드 사전을 가지고 있다 하여도 개발자가 해당 사전을 역시 수집이 가능하므로 금지 비밀번호를 갱신하면 된다.


,