버퍼 오버플로우: 두 판 사이의 차이

IT위키
편집 요약 없음
(메모리를 다루는데 오류가 발생하여 잘못된 동작을 하는 프로그램 취약점)
 
(다른 사용자 한 명의 중간 판 하나는 보이지 않습니다)
1번째 줄: 1번째 줄:
[[분류:보안]][[분류:보안 취약점]][[분류:정보보안기사]]
[[분류:보안]]
[[분류:보안 취약점]]
[[분류:정보보안기사]]
 
;프로세스 메모리 영역 중 버퍼에 초과값을 입력하여 시스템을 중지시키거나 원하는 동작을 하도록 조작할 수 있다.
;프로세스 메모리 영역 중 버퍼에 초과값을 입력하여 시스템을 중지시키거나 원하는 동작을 하도록 조작할 수 있다.
;<nowiki>버퍼 오버플로우 : 메모리를 다루는 데 오류가 발생하여 잘못된 동작을 하는 프로그램 취약점(정처기 20년 3회 기출)</nowiki>


== 종류 ==
==종류==
===스택 버퍼 오버플로우===
===스택 버퍼 오버플로우===
;Stack Buffer Overflow
;Stack Buffer Overflow
* 주로 SetUID가 설정된(루트 권한으로 실행되는) 프로그램들을 타겟으로 한다.
* 입력값에 수용 가능한 버퍼보다 큰 값을 입력하여 임의의 공격코드를 루트 권한으로 실행시킨다.


* '''원리'''
*주로 SetUID가 설정된(루트 권한으로 실행되는) 프로그램들을 타겟으로 한다.
** 프로그램에서 특정 함수를 실행시키면 스택에 이전 함수로 돌아가기 위한 주소가 기록된다. (함수에서 return이 호출되면 그 값과 함께 돌아갈 주소)
*입력값에 수용 가능한 버퍼보다 큰 값을 입력하여 임의의 공격코드를 루트 권한으로 실행시킨다.
** 버퍼에 큰 값을 넣게 되면 이 스택 영역을 침범하게 된다.
 
** 리턴 주소가 들어갈 곳에 쉘코드나 다른 프로그램의 주소를 넣으면 그것이 실행되게 된다.
*'''원리'''
**프로그램에서 특정 함수를 실행시키면 스택에 이전 함수로 돌아가기 위한 주소가 기록된다. (함수에서 return이 호출되면 그 값과 함께 돌아갈 주소)
**버퍼에 큰 값을 넣게 되면 이 스택 영역을 침범하게 된다.
**리턴 주소가 들어갈 곳에 쉘코드나 다른 프로그램의 주소를 넣으면 그것이 실행되게 된다.
 
===힙 버퍼 오버플로우===
===힙 버퍼 오버플로우===
;Heap Buffer Overflow
;Heap Buffer Overflow
* 힙 데이터 영역에서 일어나는 버퍼 오버플로이다.
* 스택 오버플로우만큼 흔히 사용가능한 공격은 아니다.
* 동적 메모리 할당 연결(malloc 상위 수준 데이터)을 덮어씀으로써 프로그램 함수 포인터를 조작한다.


== 방어 기법 ==
*힙 데이터 영역에서 일어나는 버퍼 오버플로이다.
* '''스택가드'''
*스택 오버플로우만큼 흔히 사용가능한 공격은 아니다.
** 카나리(canary)라고 불리는 무결성 체크용 값을 복귀주소와 변수 사이에 삽입해 둔다.
*동적 메모리 할당 연결(malloc 상위 수준 데이터)을 덮어씀으로써 프로그램 함수 포인터를 조작한다.
** 버퍼 오버플로 시 카나리값이 변하게 되는데, 이 경우 복귀주소를 호출하지 않는다.
 
** gcc등 각종 컴파일러에 이 기법이 반영되어 업데이트 되었다.
==방어 기법==
* '''스택쉴드'''
 
** 함수 시작 시 복귀주소를 Global RET라는 특수 스택에 저장해 둔다.
*'''스택가드(Stackguard)'''
** 함수 종료 시 저장된 값과 스택의 RET값을 비교해 다를 경우 오버플로우로 간주하고 프로그램 실행을 중단한다.
**카나리(canary)라고 불리는 무결성 체크용 값을 복귀주소와 변수 사이에 삽입해 둔다.
* '''ASLR(Address Space Layout Randomization)'''
**버퍼 오버플로 시 카나리값이 변하게 되는데, 이 경우 복귀주소를 호출하지 않는다.
** 메모리 공격을 방어하기 위해 주소 공간 배치를 난수화 한다.
**gcc등 각종 컴파일러에 이 기법이 반영되어 업데이트 되었다.
** 실행 시 마다 메모리 주소를 변경시켜 버퍼 오버플로우를 통한 특정주소 호출을 차단한다.
*'''스택쉴드(Stack Shield)'''
** 리눅스에서 다음과 같이 설정할 수 있다.
**함수 시작 시 복귀주소를 Global RET라는 특수 스택에 저장해 둔다.
<pre class='shell'>
**함수 종료 시 저장된 값과 스택의 RET값을 비교해 다를 경우 오버플로우로 간주하고 프로그램 실행을 중단한다.
*'''ASLR(Address Space Layout Randomization)'''
**메모리 공격을 방어하기 위해 주소 공간 배치를 난수화 한다.
**실행 시 마다 메모리 주소를 변경시켜 버퍼 오버플로우를 통한 특정주소 호출을 차단한다.
**리눅스에서 다음과 같이 설정할 수 있다.
<pre class="shell">
echo 2 > /proc/sys/kernel/randomize_va_space
echo 2 > /proc/sys/kernel/randomize_va_space
</pre>
</pre>


* '''실행 불가능한 영역'''
*'''실행 불가능한 영역'''
** Solaris 2.7이상 버전에서 /etc/system 파일에 noexec_user_stack, noexec_user_stack_log를 1로 set하여 활성화시킨다
**Solaris 2.7이상 버전에서 /etc/system 파일에 noexec_user_stack, noexec_user_stack_log를 1로 set하여 활성화시킨다
** 스택과 힙을 실행 불가능(No Executable)한 영역으로 만든다.
**스택과 힙을 실행 불가능(No Executable)한 영역으로 만든다.


* '''안전한 개발'''
*'''안전한 개발'''
** 프로그램 개발 시 입력값에 대한 크기 검증을 적절히 수행하거나 취약하지 않은 함수만을 사용한다면 어느정도 방지할 수 있다.
**프로그램 개발 시 입력값에 대한 크기 검증을 적절히 수행하거나 취약하지 않은 함수만을 사용한다면 어느정도 방지할 수 있다.
** '''참고'''
**'''참고'''
*** 버퍼 오버플로우에 취약한 언어들 : C, C++
***버퍼 오버플로우에 취약한 언어들 : C, C++
*** 버퍼 오버플로우에 취약한 함수들 : strcat(), strcpy(), gets(), scanf(), sscanf(), vscanf(), vsscanf(), sprintf(), vsprintf(), gethostbyname()
***버퍼 오버플로우에 취약한 함수들 : strcat(), strcpy(), gets(), scanf(), sscanf(), vscanf(), vsscanf(), sprintf(), vsprintf(), gethostbyname()
*** 대신 사용이 권장되는 함수들 : strncat(), strncpy(), fgets(), fscanf(), vfscanf(),snprintf(), vsnprintf()
***대신 사용이 권장되는 함수들 : strncat(), strncpy(), fgets(), fscanf(), vfscanf(),snprintf(), vsnprintf()

2022년 6월 30일 (목) 10:40 기준 최신판


프로세스 메모리 영역 중 버퍼에 초과값을 입력하여 시스템을 중지시키거나 원하는 동작을 하도록 조작할 수 있다.
버퍼 오버플로우 : 메모리를 다루는 데 오류가 발생하여 잘못된 동작을 하는 프로그램 취약점(정처기 20년 3회 기출)

종류[편집 | 원본 편집]

스택 버퍼 오버플로우[편집 | 원본 편집]

Stack Buffer Overflow
  • 주로 SetUID가 설정된(루트 권한으로 실행되는) 프로그램들을 타겟으로 한다.
  • 입력값에 수용 가능한 버퍼보다 큰 값을 입력하여 임의의 공격코드를 루트 권한으로 실행시킨다.
  • 원리
    • 프로그램에서 특정 함수를 실행시키면 스택에 이전 함수로 돌아가기 위한 주소가 기록된다. (함수에서 return이 호출되면 그 값과 함께 돌아갈 주소)
    • 버퍼에 큰 값을 넣게 되면 이 스택 영역을 침범하게 된다.
    • 리턴 주소가 들어갈 곳에 쉘코드나 다른 프로그램의 주소를 넣으면 그것이 실행되게 된다.

힙 버퍼 오버플로우[편집 | 원본 편집]

Heap Buffer Overflow
  • 힙 데이터 영역에서 일어나는 버퍼 오버플로이다.
  • 스택 오버플로우만큼 흔히 사용가능한 공격은 아니다.
  • 동적 메모리 할당 연결(malloc 상위 수준 데이터)을 덮어씀으로써 프로그램 함수 포인터를 조작한다.

방어 기법[편집 | 원본 편집]

  • 스택가드(Stackguard)
    • 카나리(canary)라고 불리는 무결성 체크용 값을 복귀주소와 변수 사이에 삽입해 둔다.
    • 버퍼 오버플로 시 카나리값이 변하게 되는데, 이 경우 복귀주소를 호출하지 않는다.
    • gcc등 각종 컴파일러에 이 기법이 반영되어 업데이트 되었다.
  • 스택쉴드(Stack Shield)
    • 함수 시작 시 복귀주소를 Global RET라는 특수 스택에 저장해 둔다.
    • 함수 종료 시 저장된 값과 스택의 RET값을 비교해 다를 경우 오버플로우로 간주하고 프로그램 실행을 중단한다.
  • ASLR(Address Space Layout Randomization)
    • 메모리 공격을 방어하기 위해 주소 공간 배치를 난수화 한다.
    • 실행 시 마다 메모리 주소를 변경시켜 버퍼 오버플로우를 통한 특정주소 호출을 차단한다.
    • 리눅스에서 다음과 같이 설정할 수 있다.
echo 2 > /proc/sys/kernel/randomize_va_space
  • 실행 불가능한 영역
    • Solaris 2.7이상 버전에서 /etc/system 파일에 noexec_user_stack, noexec_user_stack_log를 1로 set하여 활성화시킨다
    • 스택과 힙을 실행 불가능(No Executable)한 영역으로 만든다.
  • 안전한 개발
    • 프로그램 개발 시 입력값에 대한 크기 검증을 적절히 수행하거나 취약하지 않은 함수만을 사용한다면 어느정도 방지할 수 있다.
    • 참고
      • 버퍼 오버플로우에 취약한 언어들 : C, C++
      • 버퍼 오버플로우에 취약한 함수들 : strcat(), strcpy(), gets(), scanf(), sscanf(), vscanf(), vsscanf(), sprintf(), vsprintf(), gethostbyname()
      • 대신 사용이 권장되는 함수들 : strncat(), strncpy(), fgets(), fscanf(), vfscanf(),snprintf(), vsnprintf()