본문 바로가기
  • 시 쓰는 개발자
CS 개념/컴퓨터 보안

컴퓨터 보안 (4) - OS Security 2

by poetDeveloper 2024. 4. 25.

시험공부하며 러프하게 정리한 내용이니, 가볍게 참고만 하시길

 

Set-UID Privileged(권한) Programs

 

* Types of Privileged Programs

- Daemons : 백그라운드에서 실행되는 프로그램. root 권한이 필요하다.

- SET-UID program : 특수 비트가 표시된 프로그램. 일시적으로 상승된 권한을 부여함. (비밀번호 바꾸기 등)

 

* SET-UID Concepts : 2개의 User ID를 가진다.

- Real UID (RUID) : 프로세스 실제 소유자를 식별

- Effective UID (EUID) : 프로세스의 권한을 식별

     일반 프로그램은 RUID = EUID이다.

     그러나 SET-UID가 실행되면 달라진다. RUID는 사용자를 나타내지만 EUID는 프로그램 소유자의 ID와 동일하다.

          → 권한이 상승되었으므로, 만약 프로그램이 루트 소유면 루트 권한으로 실행됨.

 

EX1) 파일 소유자를 루트로 변경 : sudo chown root Filename

EX2) SET-UID 설정 : sudo chmod 4775 Filename

 

* SET-UID의 보안

- 제한된 행동을 전제로 둠. ex) 자기 비밀번호 아는 사람만 비밀번호 변경이 가능

- 특정 콘텐츠에 대해서만, 특정 방식으로 변경하도록 제한을 둠.

- 당연히 모든 프로그램을 SET-UID 설정하는 것은 안좋음.

 

* 환경 변수 공격 : PATH 변수를 조작하여 명령이 발견되는 방식을 변경

ex) ls라고 쳤을 때 리스트 나오는 게 아니고 다른 명령어가 실행되도록 조작하는 것

 

* Capability Leaking 기능 유출 : 권한을 다운그레이드 시켜서 기능을 유출함.

- 권한 다운그레이드 시키고, close file 문구를 지워서 파일을 안닫음. 이러면 파일이 계속 열려있어서 기능이 유출될 수 있음.

 

* File Descriptor : 프로세스에서 특정 파일에 접근할 때 사용하는 추상적인 값

 

* execve() : 안전하게 프로그램을 호출하는 함수

- execve(명령이름, 입력데이터, 0)

- 왜 안전한가? : 코드와 데이터가 명확히 분리되어 있기 때문에 사용자 데이터가 코드가 될 수 있는 방법이 없음.


Buffer Overflow Attacks

 

* Exploit : 버그 결함이나 취약점을 이용해 공격을 일으키는 모든 입력을 의미

 

* Buffer Overflow

- 가장 일반적인 OS 공격

- 개발자가 입력 문자열의 길이를 제한하지 않았을 때, 버퍼 길이를 초과하는 입력을 해 입력 문자열이 일부 메모리를 덮어 씌워버림. 이때문에 애플리케이션이 예기치 않게 동작함. 만약 덮어진 문자열에 악성 코드를 넣는다면 공격할 수 있는 것임.

- 공격자의 목표 : 높은 권한을 가진 shell을 확보하는 것.

- 공격하는 방법 : 루트 권한을 가진 프로그램을 공격. 약점 찾고 → 프로그램 리버스 엔지니어링 → 익스플로잇 빌드

- 공격 종류 : 힙 스매싱, 스택 스매싱

EX) 버퍼가 0~99번지라면 100번지부터 악성코드가 실행되도록 놓고 버퍼 오버플로우 공격을 하는 것임.

 

* 주소 공간

- 대부분의 커널은 가상 메모리를 써서 process에 메모리를 할당함.

 

* strcpy() 와 strncpy()

- strcpy(dest, src) :src를 dest로 복사한다. src가 더 길다면 dest의 자리를 덮어 씌워버릴 수 있으므로 버퍼 오버플로우에 취약하다. 또한, 제약없이 복사해버리니까 null이 상황 상관없이 자동으로 추가된다.

- strncpy(dest, src, n) : src를 dest로 복사할 문자 수 n개만큼 복사한다. 만약 오버플로우 된다면, 그 문자들은 삭제된다. 어디서 끊길지 모르므로 null은 수동으로 추가해줘야한다.

 

* 버퍼 오버플로우 대응책

- 버퍼를 동적 할당한다.

- 개발자 : strncpy(), strncat() 등 복사 전 데이터 길이를 확인하는 "안전한 라이브러리"를 사용한다.

- OS : ASLR 적용 (스택 위치 무작위화, 바로 아래 설명 있음)

- 컴파일러 : Stack-guard 사용 (밑에 설명)

- 하드웨어 : 실행 불가능한 Stack 사용하기 (밑에 설명)

+) JAVA에서는 일어나지 않는 문제이다. 객체를 힙에 동적할당하고, 포인터가 없기 때문이다.

 

* ASLR( 스택 위치 무작위화 )의 원리 : 코드가 메모리에 로드될 때마다 스택 주소를 바꿔준다.

- kernel.randomize_va_space 값에 따라 달라진다.

     kernel~~space = 0 : 주소 공간 무작위 지정 안함. 즉, 버퍼 오버플로우 "허용"

     kernel~~space = 1 : 스택 메모리 주소만 랜덤화 한다.

     kernel~~space = 2 : 스택과 힙의 메모리 주소 둘 다 랜덤화 한다.

 

* Stack Guard (카나리아) : 컴파일러 접근 방식의 버퍼 오버플로우 예방책이다.

- 임의의 시크릿 value를 생성 → 스택 말고 메모리에 위치시킴 → 이 값을 스택에 저장되는 함수의 로컬 변수에 할당 → 복사 함수 실행 후, 로컬 변수 값 변경 여부를 확인 → 만약 변경됐다면 버퍼 오버플로우가 발생한 것이므로 return 안하고 program exit한다.

 

* 실행 불가능한 스택 Non-Executable Stack

- NX bit는 CPU의 실행 금지 기능을 나타낸다. ( 특정 메모리 영역의 실행 불가 )

- 하지만 return-to-libc 공격을 사용하면 이런 NX 방어도 무력화시킬 수 있음.