어렵당
4. 시스템 보안 본문
- 프로세스 메모리 레이아웃(유닉스)
STACK : 함수 처리, 로컬변수/매개변수를 처리하기 위한 영역( LIFO 방식-Last In First Out, Push-Pop 이용 )
HEAP : 동적 메모리 할당영역(malloc 같은 함수로 필요할때 자유롭게 메모리 할당)
BSS : 초기화되지 않은 전역변수,정적변수가 위치
데이터 영역 : 초기화된 전역변수,정적변수가 위치
TEXT(CODE) : 기계어로된 실행코드가 위치
레지스터 : CPU가 연산을 수행하기 위해 사용하는 고속 저장장치
Intel CPU 기준 대표적으로 아래의 레지스터가 있다
- ESP
: 스택 연산이 발생하는 스택 프레임의 최하위 포인터(SP:Stack Pointer)를 저장하고있는 레지스터
- EBP
: 스택 프레임에 기준이 되는 SFP(Stack Frame Pointer)를 저장하고 있는 레지스터
: 스택 프레임 내에서 EBP(에 있는 SFP로)를 기준으로 상대 주소로 프레임 내에 있는 변수 접근
- EIP
: 다음에 실행할 명령어의 주소값을 가지고있음
* 인터럽트(interrupt)
: 컴퓨터 시스템에 예기치 않을 일이 발생했을때 그것을 CPU에게 알려주는 것
: CPU가 계속 입출력 상태를 검사하지 않고 입출력장치가 데이터를 전송할 준비가 되면 CPU에 인터럽트를 발생시킨다. CPU는 인터럽트 신호를 받으면 프로그램 카운터(PC:Program Counter)에 있는 복귀주소를 메모리 스택에 저장한 다음 입출력 전송을 위한 인터럽트 핸들러로 제어를 이동한다
* 교착상태(deadlock)
: 동일한 자원을 공유하고 있는 두개의 컴퓨터 프로세스(프로그램)들이 상대방의 자원에 접근하는 것을 사실상 서로 방해함으로써 두 프로그램 모두 기능이 중지되는 상황
필요조건 4가지
- 상호배제 : 한번에 한 프로세스만이 자원을 사용할 수 있다
- 점유와 대기 : 프로세서가 다른 자원을 요구하면서, 자신에게 할당된 자원을 해제하지 않을 떄 발생
- 비선점 : 프로세스에 할당된 자원을 모두 사용하기 전에는 그 프로세스로부터 도중에 회수할 수 없다
- 환형 대기 : 프로세스와 자원들이 원형을 이루며 프로세스는 자신에게 할당된 자원을 가지면서 상대방 프로세스의 자원을 상호 요청하는 경우
* 스래싱(trashing)
: 프로세스 처리시간보다 페이지 교체시간이 더 많아지는 현상
: 페이지 부재(page fault)로 발생하며 프로세스의 실행에 필요한 수만큼 충분한 페이지를 갖지 못해 실행중에 계속 페이지를 교체하면서 발생
* 워킹세트(working set)(or 작업집합)
: 프로세스가 일정 시간 동안 참조하는 페이지들의 집합
* 주요 페이지 교체 알고리즘
- LRU(Least Recently Used) : 가장 오랫동안 사용되지 않은 페이지를 교체하는 알고리즘
- LFU(Least Frequently Used) : 가장 사용 횟수가 적은 페이지를 교체하는 알고리즘
- NUR(Not Used Recently) : 최근에 사용하지 않은 페이지를 교체하는 알고리즘
- FIFO(First In First Out) : 가장 먼저 적재한 페이지부터 교체하는 알고리즘
* 스왑 공간(Swap Space) : 보조기억장치의 일정영역으로 메모리가 부족할 경우 마치 메모리처럼 사용하는 공간
-------------------------------------
스택 버퍼 오버플로우
: 정의된 버퍼의 한계치를 넘는 경우 발생하며 복귀주소(RET)에 공격자가 원하는 명령을 수행하게끔 하는 공격
예방방법 :
- strcpy 대신 문자열 길이를 체크하는 strncpy 함수를 사용
- 입력값을 사전에 검증하여 방지
예시)
if(strlen(argv[1]) >= sizeof(buffer)){
fprintf(stderr,"입력된 문자열이 버퍼사이즈 보다 커서 버퍼오버플로우 공격이 발생될수있음. 프로그램을 종료 \n");
exit(1);
}
[ 또는 strlen(argv[1]) > sizeof(buffer)-1 ]
[ 문자열 입력시 문자열의 끝을 시스템에서 파악하기 위해서 \0이 끝에 붙음. 그래서 4byte를 입력해도 용량은 5byte가 됨 ]
- 스택 오버플로우 대응 기술 사용
1. 스택 가드 : 메모리상에서 복귀주소(RET)와 변수 사이에 특정값을 저장해 두고 그값이 변경될 경우 오버플로우로 탐지
( 오버 플로우가 발생되지 않으면 그 특정값은 변경될 일이 없음 )(카나리 단어 기법 이라고도 함)
2. 스택 쉴드 : 함수 시작 시 복귀주소(RET)를 Global RET라는 특수 스택에 저장했다가 함수 종료 시 비교하여 다를경우 오버플로우로 탐지
3. ASLR(Address Space Layout Randomization) : 공간 배치를 난수화. 실행 시마다 메모리 주소를 변경시켜 악성코드에 의한 특정 주소 호출을 방지
( randomize_va_space 0 = 사용 X )
( randomize_va_space 1 = 힙 의외는 모두 랜덤하게 설정 )
( randomize_va_space 2 = 모두 랜덤하게 설정 )
* C언어 취약한 함수 및 안전한 함수(_s 추가)
strcat() -> strcat_s()strncat() -> strncat_s()strcpy() -> strcpy_s()strncpy() -> strncpy_s()sprintf() -> sprintf_s()gets() -> gets_s()scanf() -> scanf_s()
-------------------------------------
힙 버퍼 오버플로우
: 힙에 할당된 버퍼들에 문자열 등이 저장될 때 정의된 힙의 메모리 사이즈를 초과하여 저장되는 경우 오버플로우가 발생하여 데이터/함수 주소들을 변경하여 공격자가 원하는 코드를 실행할수있다
-------------------------------------
레이스 컨디션 공격(Race Condition Attack)
: 둘 이상의 프로세스/스레드 간에 공유 자원에 접근했을때 접근 순서에 따라 원하지 않는/비정상적인 결과가 발생할 수 있는 상태 및 조건
: 프로세스가 만든 임시파일을 공격자가 악의적인 프로그램을 통해 프로세스 실행 중에 끼어들어 임시파일을 목적파일로 연결(심볼릭 링크)하여 악의적인 행위를 할 수 있는데 이를 레이스 컨디션 공격이라고 한다
: 만약 프로세스가 setuid가 설정이 되어있다면 권한 상승을 통해 중요 자원에 접근하는 문제가 발생할 수 있다.
예시) A프로세스의 연산이 아직 끝나지 않았는데 context switching(프로세스 제어권이 다른 프로세스로 넘어가는것)이 발생하여 B프로세스가 자원을 변경시키고 다시 context switching가 발생했을때 A프로세스는 비정상적인 결과를 출력
* 문맥(Context)과 문맥교환(Context Switching)
문맥(Context) : 특정 프로세스와 관련된 정보들의 총집합
문맥교환(Context Switching) : 실행 상태의 프로세스를 다른 프로세스로 교체하기 위하여 문맥(Context)를 각각 저장/재적재하는 것을 의미
* 경쟁상태가 발생할 수 있는 코드영역 : 임계 영역(Critial Section)
* 프로세스에 SetUID가 설정되어있고 임시파일을 생성하는 경우 공격자는 임시파일을 지우고 중요파일(root권한)과 심볼릭 링크로 연결할 수 있게 임시파일을 새로 생성한다. 이 과정을 반복해서 아다리 맞게 수행되면 공격이 성공
레이스 컨디션 해결방안 - 동기화(Synchronization)
: 접근순서 제어, 동시 접근 배제를 수행
: A프로세스 연산이 끝날때까지는 자물쇠를 걸어서 context switching 가 발생되어도 자원을 변경하지 못함
: Mutex, semaphore 같은 커널에서 제공해주는 서비스가 필요
대응방안
1. 가능하면 임시파일을 생성하지 않는다
2. 파일 생성 시 이미 동일한 파일이 존재하는 경우 쓰기를 금지한다
3. 사용하고자 하는 파일에 링크가 걸려있으면 실행을 중지
4. umask를 최하 022정도로 유지하여 임시로 생성한 파일이 공격자에 의해 악의적으로 삭제되지 않도록 한다.
(임시 디렉터리에 쓰기 권한을 제거해서 공격자가 파일을 삭제할 수 없도록 한다)
-------------------------------------
포맷 스트링 공격(Format String Attack)
: 포맷 스트링은 C언어의 printf()등의 함수에서 사용되는 문자열의 입출력 형태를 정의하는 문자열로 서식 문자열이라 표현, 다양한 타입의 데이터를 문자열로 출력하기 위함
: 외부로부터 입력된 값을 검증하지 않고 입출력 함수의 포맷 스트링을 그대로 사용하는 경우 포맷 스트링 공격을 이용하여 메모리 내용을 읽거나 쓸수있고, 취약한 프로세스의 권한을 획득하여 임의의 코드를 실행할 수 있다
* 보안 위협 3가지 : 프로세스 공격(종료), 프로세스 메모리 읽기(확인), 프로세스 메모리 변조를 악용한 임의코드 실행
: 서식 문자열을 지정하지 않고( ex : printf(argv[1]); ) 사용자 입력값 그대로 받게되면 공격자는 이를 조작하여 메모리 내용을 참조하고 특정 영역의 값을 변경할 수 있다.
: 공격자는 스택 프레임 구조를 고려하면서 "%x"를 통해 메모리 내용을 참조할 수 있고, 지정한값을 넘어서 RET 주소까지도 확인이 가능하다. 확인된 RET 주소를 %n 또는 %hn 식별자를 통해서 악성코드가 위치한 주소로 변조도 가능하다
( ex : ./code "%8x %8x %8x %8x" )
- 포맷 스트링 식별자
%d : 10진 정수
%f : 실수
%c : 문자
%s : 문자열
%x : 16진수 정수
%n : 이전까지 출력한 총 바이트 수(4바이트 단위)를 지정한 변수에 저장
%hn : 2바이트 단위로 저장
대응방안
: 포맷스트링을 서식문자를 지정하여 간접적으로 참조가 되도록 한다
printf(argv[1]); -> printf("%s", argv[1]);
-------------------------------------
Pass the Hash 공격
: 패스워드에 대한 해시값을 인증 시에 사용하는 환경에서 사용자의 해시값을 탈취한 후 이를 이용하여 인증을 시도하는 형태의 공격으로 원격서버나 원격 서비스에 접속할 때 사용자의 실제 패스워드를 모르는 상태에서도 탈취한 사용자의 패스워드 해시값을 이용하여 인증을 시도한다
-------------------------------------
크리덴셜 스터핑(Credential Stuffing)
: 무작위 대입 공격의 일종으로 공격자가 미리 확보해높은 사용자의 로그인 자격증명(ID/PW 등)을 다른 사이트의 인증시스템 계정에 무작위로 대입하여 접속을 시도하는 공격기법
-------------------------------------
'학습 > 알기사 정보보안기사 정리' 카테고리의 다른 글
6. 애플리케이션 보안 (0) | 2024.10.13 |
---|---|
5. 네트워크 보안 (1) | 2024.10.05 |
2. 리눅스/유닉스 기본 (0) | 2024.10.04 |
1. 윈도우 보안 (0) | 2024.10.03 |
3. 리눅스/유닉스 로그파일 (3) | 2024.10.03 |